C - Create dynamic matrix with values - c

i try to create dynamic matrix and enter values with scanf.
Its work only for 1 row, when i increase the error begins.
Can not make progress from the first line and thus can not get values.
int main()
{
int **matrix1;
BuildMatrix(&matrix1, 3, 3);
}
void BuildMatrix(int*** matrix, int row, int column)
{
int i, j, flag = 1, num;
*matrix = (int**)malloc(row * sizeof(int*));
if (*matrix == NULL)
{
printf("Not enough memory!\n");
}
else
{
for (i = 0; i < row && flag; i++)
{
*matrix[i] = (int* )malloc(column * sizeof(int));
if (*matrix[i] == NULL)
{
printf("Not enough memory!\n");
for (j = 0; j < i; j++)
{
free(*matrix[j]);
flag = 0;
}
free(*matrix);
}
}
if (flag)
{
for (i = 0; i < row; i++)
{
for (j = 0; j < column; j++)
{
scanf("%d", &*matrix[i][j]);
}
}
}
}
}

Due to operator precedence, the expression *matrix[i] is equal to *(matrix[i]). That is, it dereferences matrix[i] and not matrix.
You need to use (*matrix)[i] instead.

Related

I want to show elements of a matrix that appear only once

I got this but it I can't seem to make it work, tried everything I could think of.
#include <stdio.h>
#include <stdlib.h>
void alocare_vector(int *v, int nr, int elem)
{
int *v1;
if ((v1 = realloc(v, nr * sizeof(int))) == NULL)
{
printf("Memorie insuficienta");
free(v);
exit(EXIT_FAILURE);
}
v = v1;
v[nr - 1] = elem;
}
int main()
{
int a[100][100];
int n, *v = NULL, i, j, k, l, ok = 0, nr = 0;
printf("Number de elements n:");
scanf("%d", &n);
for (i = 0; i < n; i++)
for (j = 0; j < n; j++)
scanf("%d", &a[i][j]);
for (k = 0; k < n; k++)
{
for (l = 0; l < n; l++)
{
for (i = 0; i < n; i++)
for (j = 0; j < n; j++)
if (a[k][l] == a[i][j] && (k != i && l != j))
ok = 1;
if (ok == 0)
{
nr++;
alocare_vector(v, nr, a[k][l]);
}
ok = 0;
}
}
if (nr > 0)
{
printf("Elements:");
for (i = 0; i < nr; i++)
{
printf("%d ", v[i]);
}
}
free(v);
}
Basically, I need to create a matrix, ans print the elements that appear only once using an array with dynamic memory allocation.
one simple fix is to declare the "int * v" as a global variable and modify the function as alocare_vector(int nr, int elem)
now using a hash table you can store the numbers in the array, below is the your implementation just a bit modified.
#include <stdio.h>
#include <stdlib.h>
int hash[1000]={0};
int * v=NULL;
void alocare_vector(int nr, int elem)
{
int *v1;
if ((v1 = (int*)realloc(v, nr * sizeof(int))) == NULL)
{
printf("Memorie insuficienta");
free(v);
exit(EXIT_FAILURE);
}
v = v1;
v[nr - 1] = elem;
}
int main()
{
int a[100][100];
int n, i, j, nr = 0;
printf("Number de elements n:");
scanf("%d", &n);
for (i = 0; i < n; i++)
{
for (j = 0; j < n; j++)
{
scanf("%d", &a[i][j]);
++hash[a[i][j]];
}
}
for (i = 0; i < n; i++)
{
for (j = 0; j < n; j++)
{
if(hash[a[i][j]]==1)
{
nr++;
alocare_vector(nr, a[i][j]);
}
}
}
if (nr > 0)
{
printf("Elements:");
for (i = 0; i < nr; i++)
{
printf("%d ", v[i]);
}
}
free(v);
}
When calling a your funtion you pass a copy of the pointer. Therfore any modifications to this local copy of the pointer will not affect the copy in main. Therfore you need a refrence or pointer to the pointer in main.
void alocare_vector(int **v, int nr, int elem)
{
...
*v = v1;
}
Here you have brut force example how to generate array of distinct elements of the 2D array:
typedef struct
{
size_t length;
int data[];
}data_t;
data_t *add_element(data_t *arr, int element)
{
size_t newsize = arr ? arr -> length : 0;
arr = realloc(arr, newsize * sizeof(arr -> data[0]) + sizeof(*arr));
if(arr)
{
arr -> length = newsize;
arr -> data[newsize - 1] = element;
}
return arr;
}
int isPresent(size_t rows, size_t cols, size_t vrow, size_t vcol, int (*array)[cols])
{
int val = array[vrow][vcol];
for(size_t row = 0; row < rows; row++)
for(size_t col = 0; col < cols; col++)
{
if(vcol == col && vrow == row) continue;
if(array[row][col] == val)
{
return 1;
}
}
return 0;
}
data_t *distinctElements(size_t rows, size_t cols, int (*array)[cols])
{
data_t *dist = NULL;
for(size_t row = 0; row < rows; row++)
{
for(size_t col = 0; col < cols; col++)
{
if(!isPresent(rows, cols, row, col, array))
{
data_t *tmp = add_element(dist, array[row][col]);
if(tmp) dist = tmp;
else { /* error handling */}
}
}
}
return dist;
}

Building a function using Dynamic memory allocation

#include <stdio.h>
#include <stdlib.h>
void addition(int column, int row) {
int **array_a = (int **)malloc(sizeof(int*) * column);
int **array_b = (int **)malloc(sizeof(int*) * column);
int **array_c = (int **)malloc(sizeof(int*) * column);
for (int i = 0; i < column; i++) {
array_a[i] = (int *)malloc(sizeof(int) * row);
}
for (int i = 0; i < column; i++) {
for (int k = 0; k < row; k++) {
array_a[i][k] = rand();
}
for (int i = 0; i < column;) {
array_b[i] = (int *)malloc(sizeof(int) * row);
}
for (int i = 0; i < column; i++) {
for (int k = 0; k < row; k++) {
array_b[i][k] = rand();
}
}
for (int i = 0; i < column;) {
array_c[i] = (int *)malloc(sizeof(int) * row);
}
for (int i = 0; i < column; i++) {
for (int k = 0; k < row; k++) {
array_c[i][k] = array_a[i][k] + array_b[i][k];
}
}
for (int i = 0; i < column; i++) {
for (int k = 0; k < row; k++) {
printf("%d ", array_c[i][k]);
}
free(array_a);
free(array_b);
free(array_c);
}
}
}
int main(void) {
int column, row;
scanf("%d" "%d", &column, &row);
addition(column, row);
return 0;
}
I'm building a function that creates two 2D arrays and fills the values with random numbers and combines their values.
There is no error but the printf isn't working. Any way to make it work?
I don't know how to explain in more details but if you ask me I'll answer.
There are multiple problems in your code:
the loops are not properly nested: the body of the second for (int i = 0; i < column; i++) loop should stop right after the nested for for (int k = 0; k < row; k++) loop.
there are missing i++ increments in some of the loops: for (int i = 0; i < column;) should be
for (int i = 0; i < column; i++)
This is the main issue as it causes an infinite loop, repeatedly initializing array_b[0] with a newly allocated block, until memory is exhausted and beyond.
you do not check for memory allocation failure.
your use or columns and rows is odd: the first index in a 2D usually refers to rows and the second to columns, but since your usage is consistent, it is probably not a problem.
you do not output a newline after each row or column: all output is produced on a single line without a trailing newline. This may cause your output to not appear on some systems. You might want to pause the program after the output to let the user see the output.
casting the return value of malloc() is not necessary in C.
you do not free the subarrays.
Here is a modified version:
#include <stdio.h>
#include <stdlib.h>
int **allocate_array(int column, int row) {
int **array = malloc(sizeof(array[0]) * column);
if (array == NULL)
return NULL;
for (int i = 0; i < column; i++) {
array_a[i] = malloc(sizeof(array[i][0]) * row);
if (array_a[i] == NULL) {
while (i-- > 0) {
free(array[i]);
}
free(array);
return NULL;
}
}
return array;
}
void free_array(int **array, int column, int row) {
if (array) {
for (int i = 0; i < column; i++) {
free(array[i]);
}
free(array);
}
}
void addition(int column, int row) {
int **array_a = allocate_array(column, row);
int **array_b = allocate_array(column, row);
int **array_c = allocate_array(column, row);
if (array_a && array_b && array_c) {
for (int i = 0; i < column; i++) {
for (int k = 0; k < row; k++) {
array_a[i][k] = rand();
}
}
for (int i = 0; i < column; i++) {
for (int k = 0; k < row; k++) {
array_b[i][k] = rand();
}
}
for (int i = 0; i < column; i++) {
for (int k = 0; k < row; k++) {
array_c[i][k] = array_a[i][k] + array_b[i][k];
}
}
for (int i = 0; i < column; i++) {
for (int k = 0; k < row; k++) {
printf("%d ", array_c[i][k]);
}
printf("\n");
}
}
free_array(array_a, column, row);
free_array(array_b, column, row);
free_array(array_c, column, row);
}
int main(void) {
int column, row;
if (scanf("%d%d", &column, &row) == 2 && column > 0 && row > 0)
addition(column, row);
return 0;
}

C programming - Sodoku solution (backtracking)

the Question is: to get from the user sodoku board and if there is a solution to print it, if not to print no solution!
the solution of the soduko: two identical numbers mmust not appear on the same line;
two identical numbers must not appear in the same colum.
I worte a program that works perfectly when I put the soduko board and the size (global parametes-as shown un my code) but when I tried to receive from the user it took so much time to run the solution and sometimes it didn't retun anything. I would like to understand why?!
#include <stdio.h>
#include <stdlib.h>
#define SIZE 5
int matrix[5][5] = {
{4,2,0,0,5},
{2,0,0,1,3},
{5,0,1,2,0},
{0,0,3,0,2},
{0,0,0,0,0},
};
void print_sudoku()
{
int i,j;
for(i=0;i<SIZE;i++)
{
for(j=0;j<SIZE;j++)
{
printf("%d ",matrix[i][j]);
}
printf("\n");
}
}
int number_unassigned(int *row, int *col)
{
int num_unassign = 0;
int i,j;
for(i=0;i<SIZE;i++)
{
for(j=0;j<SIZE;j++)
{
if(matrix[i][j] == 0)
{
*row = i;
*col = j;
num_unassign = 1;
return num_unassign;
}
}
}
return num_unassign;
}
int is_safe(int n, int r, int c)
{
int i;
for(i=0;i<SIZE;i++)
{
if(matrix[r][i] == n)
return 0;
}
for(i=0;i<SIZE;i++)
{
if(matrix[i][c] == n)
return 0;
}
return 1;
}
int solve_sudoku()
{
int row;
int col;
if(number_unassigned(&row, &col) == 0)
return 1;
int i;
for(i=1;i<=SIZE;i++)
{
if(is_safe(i, row, col))
{
matrix[row][col] = i;
if(solve_sudoku())
return 1;
matrix[row][col]=0;
}
}
return 0;
}
int main()
{
if (solve_sudoku())
print_sudoku();
else
printf("No solution!\n");
return 0;
}
and this is whe code that I used to ask the user to enter a sodoku board:
int** ReadSoduko(int n) {
int** matrix = (int**) malloc((sizeof(int*)) * n);
for(int i = 0; i < n; ++i) {
matrix[i] = malloc(sizeof(int) * n);
}
printf("\nEnter your soduko board:\n");
for(int i = 0; i < n; ++i) {
printf("Enter row [%d]: ", i);
for(int j = 0; j < n; ++j) {
scanf("%d", &matrix[i][j]);
}
}
return matrix;
}
I suspect your problem is related to one thing: #define SIZE that you are probably forgetting to update when reading dynamically. Since you use SIZE in your loops, if that is not the real size of your matrix, then it probably won't work. I've changed 2 lines and added 3 other (the lines with comments at the end). Try it now.
#include <stdio.h>
#include <stdlib.h>
int SIZE; //changed here
int** matrix; //changed here
void print_sudoku()
{
int i, j;
for (i = 0; i < SIZE; i++)
{
for (j = 0; j < SIZE; j++)
{
printf("%d ", matrix[i][j]);
}
printf("\n");
}
}
int number_unassigned(int* row, int* col)
{
int num_unassign = 0;
int i, j;
for (i = 0; i < SIZE; i++)
{
for (j = 0; j < SIZE; j++)
{
if (matrix[i][j] == 0)
{
*row = i;
*col = j;
num_unassign = 1;
return num_unassign;
}
}
}
return num_unassign;
}
int is_safe(int n, int r, int c)
{
int i;
for (i = 0; i < SIZE; i++)
{
if (matrix[r][i] == n)
return 0;
}
for (i = 0; i < SIZE; i++)
{
if (matrix[i][c] == n)
return 0;
}
return 1;
}
int solve_sudoku()
{
int row;
int col;
if (number_unassigned(&row, &col) == 0)
return 1;
int i;
for (i = 1; i <= SIZE; i++)
{
if (is_safe(i, row, col))
{
matrix[row][col] = i;
if (solve_sudoku())
return 1;
matrix[row][col] = 0;
}
}
return 0;
}
int** ReadSoduko(int n) {
int** matrix = (int**)malloc((sizeof(int*)) * n);
for (int i = 0; i < n; ++i) {
matrix[i] = (int*) malloc(sizeof(int) * n);
}
printf("\nEnter your soduko board:\n");
for (int i = 0; i < n; ++i) {
printf("Enter row [%d]: ", i);
for (int j = 0; j < n; ++j) {
scanf("%d", &matrix[i][j]);
}
}
return matrix;
}
int main()
{
printf("Size of matrix: "); //added this
scanf("%d", &SIZE); //added this
matrix = ReadSoduko(SIZE); //added this
if (solve_sudoku())
print_sudoku();
else
printf("No solution!\n");
return 0;
}
And don't forget that the matrix that you have declared statically doesn't have a solution! I have tested the same matrix, just replacing the 2 in first line by a 0 and it worked here.

finding a Kaprekar numbers inside a 2D array in C

I need a function to find out the Kaprekar numbers inside this 2d array, I searched in web but none of the results worked for 2D array.
This is the array that I made:
int **matrix;
int row, column;
long s, k;
srand(time(NULL));
printf("Number of rows: ");
scanf("%d", &row);
printf("Number of column: ");
scanf("%d", &column);
matrix = (int **) calloc(row, sizeof(int*));
for(i = 0; i < row; i++)
matrix[i] = (int *) calloc(column, sizeof(int));
for(s = 0; s < row; s++)
{
for(k = 0; k < column; k++)
{
matrix[s][k]=(rand()%1000) * (rand()%1000);
}
}
any help or suggestions to convert this code to be able to work for 2D array?
bool iskaprekar(int n)
{
if (n == 1)
return true;
int sq_n = n * n;
int count_digits = 0;
while (sq_n)
{
count_digits++;
sq_n /= 10;
}
sq_n = n*n;
for (int r_digits=1; r_digits<count_digits; r_digits++)
{
int eq_parts = pow(10, r_digits);
if (eq_parts == n)
continue;
int sum = sq_n/eq_parts + sq_n % eq_parts;
if (sum == n)
return true;
}
return false;
}
You have 2D array, you have also the function that verifies the number is Kaprekar or not. The simple way is using the for loop to check all number in 2D array as you did when you initialize the values of array using rand() function.
for(s = 0; s < row; s++) {
for(k = 0; k < column; k++) {
if(iskaprekar(matrix[s][k])) {
printf("%d ", matrix[s][k]);
}
}
}
if you want to store all Kaprekar numbers, you can use pointer then reallocate for it after each time you meet one Kaprekar number. Then remove the duplicated numbers if you want.
int * numbers = 0;
if(!numbers) {return -1;}
int count = 0;
for(s = 0; s < row; s++) {
for(k = 0; k < column; k++) {
if(iskaprekar(matrix[s][k])) {
numbers = realloc(numbers, sizeof(int) (count+1));
if(!numbers) {return -1;}
numbers[count] = matrix[s][k];
count++;
}
}
}
// Remove the duplicated numbers here, if you want

Creating a new array without duplicate integers from an array in C

I was asked to create a new array without duplicate integars from an array.
I think I made a mistake in my code but can't notice anything wrong.
The output for "1, 2, 1, 2, 1, 4" is "1, 2, 2, 4".
It's supposed to be "1, 2, 4"
Would like to learn about my mistake.
// Exercise 2 -
void Ex2() {
int i, counter = 1, size = -1;
int* array = input_dynamic_array(&size);
int* newArr = (int*)malloc((size)* sizeof(int));
newArr[0] = array[0];
assert(array);
for (i = 1; i < size; i++) {
if (!find_num_in_newArr(newArr, size, array[i])) {
newArr[counter++] = array[i];
}
}
newArr = (int*)realloc(newArr, (counter)*sizeof(int));
printArray(newArr, counter);
free(array);
free(newArr);
}
bool find_num_in_newArr(int *newArr, int size, int num) {
int i;
for (i = 0; i < size; i++) {
if (newArr[i] == num) {
return true;
}
return false;
}
}
int* input_dynamic_array(int *size)
{
int *array;
int ii;
printf("Enter array size: ");
scanf("%d", size);
array = (int*)malloc((*size) * sizeof(int));
assert(array);
printf("Enter %d integer numbers: ", *size);
for (ii = 0; ii < *size; ii++)
scanf("%d", array + ii);
return array;
}
I see a problem here:
for (i = 0; i < size-1; i++)
{
if (newArr[i] == num)
{
return true;
}
return false;
}
This will never have another iteration. It will either return true or false from the first iteration. Thats not what you are planning for when you used a loop.
Based on your design, you might want to move return false; outside the loop.
Another advise, Don't cast the return value of malloc, its pointless.
Also,
int* newArr = (int*)malloc((size)* sizeof(int));
This needs to be followed by a check. You need to check if malloc returned NULL. If yes, then memory is not allocated and anything with modification based on newArr would be horrible.
A relative cleaner way of doing it will include using a function that looks like below:
int RemoveDuplicates(int* Arr, int length)
{
int i = 0, j = 0;
int LengthChanged = 0;
for (i = 1; i < length; i++)
{
for(j = 0; j < LengthChanged ; j++)
{
if(Arr[i] == Arr[j])
break;
}
// Copy as is if there is not duplicate element in the array
if (j == LengthChanged )
Arr[LengthChanged++] = Arr[i];
}
return LengthChanged;
}
There are 2 problems in your code:
find_num_in_newArr exits the loop with a return false; at the first iteration. move the return statement outside the loop body.
Ex2 check the whole array for duplicates instead of just the portion already copied: find_num_in_newArr(newArr, size, array[i]) should be find_num_in_newArr(newArr, i, array[i]). As posted, this code has undefined behavior.
Here is a corrected version with a few extra assertions:
// Exercise 2 -
bool find_num_in_newArr(const int *newArr, int size, int num) {
int i;
for (i = 0; i < size; i++) {
if (newArr[i] == num) {
return true;
}
}
return false;
}
int *input_dynamic_array(int *size) {
int *array;
int ii;
printf("Enter array size: ");
assert(scanf("%d", size) == 1);
assert(*size > 0);
array = (int*)malloc((*size) * sizeof(int));
assert(array != NULL);
printf("Enter %d integer numbers: ", *size);
for (ii = 0; ii < *size; ii++) {
assert(scanf("%d", array + ii) == 1);
}
return array;
}
void Ex2(void) {
int i, counter, size;
int *array = input_dynamic_array(&size);
int *newArr = (int*)malloc(size * sizeof(int));
assert(newArr != NULL);
newArr[0] = array[0];
counter = 1;
for (i = 1; i < size; i++) {
if (!find_num_in_newArr(newArr, i, array[i])) {
newArr[counter++] = array[i];
}
}
newArr = (int*)realloc(newArr, counter * sizeof(int));
assert(newArr != NULL);
printArray(newArr, counter);
free(array);
free(newArr);
}
You over complicate it a bit.
Use the correct types for the indexes (size_t)
int CheckValue(int *arr, int value, size_t size)
{
while (size--)
{
if (arr[size - 1] == value) return -1;
}
return 0;
}
int main()
{
int arr[] = {1,4,5,8,3,2,1,-1,9,-1,-1,6,8,1,5,4,2,3};
int newarr[sizeof(arr) / sizeof(arr[0])];
size_t size = 0;
for (size_t index = 0; index < sizeof(arr) / sizeof(arr[0]); index++)
{
if (!CheckValue(newarr, arr[index], size))
{
newarr[size++] = arr[index];
}
}
return 0;
}

Resources