I have to implement a function which, given a matrix of 0s and 1s, returns a new matrix that contains the coordinates of the 1s. For example: if matrix is 3x3 and the output is:
1 0 1
0 1 1
0 0 1
New matrix will be 5x2 and the output will be:
0 0
0 2
1 1
1 2
2 2
Some advice? My method would be this:
int matrix[3][3];
for (int i = 0; i < 3; i++){
for (int j = 0; j < 3; j++){
if (matrix[i][i] == 1){
//Code i need
}
}
}
The solution really depends on the requirement:
Is it allowed to allocate result matrix with the maximum size possible (in this case 9 x 2).
If point 1 is not allowed, is it strictly required to use fixed size array (no dynamic allocation). If this is the case then may need to pass the matrix twice to allocate the right size of array.
Other solution is of course by using dynamic allocation (using malloc etc).
The simplified version of option 1 & 2 is shown below:
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int matrix[3][3];
matrix[0][0] = 1;
matrix[0][1] = 0;
matrix[0][2] = 1;
matrix[1][0] = 0;
matrix[1][1] = 1;
matrix[1][2] = 1;
matrix[2][0] = 0;
matrix[2][1] = 0;
matrix[2][2] = 1;
//Solution 1 - If allowed to allocate matrix with size more than the result,
//i.e. if input is 3x3 matrix, then the maximum size of result matrix is 9 x 2
int resultMatrix1[9][2];
int usedCount1=0;
for (int i = 0; i < 3; i++){
for (int j = 0; j < 3; j++) {
if (matrix[i][j] == 1) {
resultMatrix1[usedCount1][0] = i;
resultMatrix1[usedCount1][1] = j;
usedCount1++;
} //end if
} //end for
} //end for
//Print the result
printf("\nSolution 1\n");
for (int i = 0; i < usedCount1; i++){
printf("%d %d\n", resultMatrix1[i][0], resultMatrix1[i][1]);
} //end for
//Solution 2 - strictly allocate matrix with size equal to the result.
//Without using dynamic allocation, meaning we need to have two passes.
//1st pass is to count the element which satisfy the criteria
int usedCount2=0;
for (int i = 0; i < 3; i++){
for (int j = 0; j < 3; j++) {
if (matrix[i][j] == 1) {
usedCount2++;
} //end if
} //end for
} //end for
int resultMatrix2[usedCount2][2]; //allocate the right size
int idx=0;
//2nd pass is to fill in the result matrix
for (int i = 0; i < 3; i++){
for (int j = 0; j < 3; j++) {
if (matrix[i][j] == 1) {
resultMatrix2[idx][0] = i;
resultMatrix2[idx][1] = j;
idx++;
} //end if
} //end for
} //end for
//Print the result
printf("\nSolution 2\n");
for (int i = 0; i < usedCount2; i++){
printf("%d %d\n", resultMatrix2[i][0], resultMatrix2[i][1]);
} //end for
return 0;
}
Results are the same for both solution:
Solution 1
0 0
0 2
1 1
1 2
2 2
Solution 2
0 0
0 2
1 1
1 2
2 2
If matrix[i][j] == 1 what do you know about the coordinates [i,j] ? That they are the coordinates of a 1 :)
Secondly, will the input matrix always be 3x3? If not, you'll want to store the dimensions of the matrix in variables, and use theses variables for your for loops.
Related
#include<stdio.h>
#define NUM_ROWS 3
#define NUM_COLS 5
int main(void){
int a[NUM_ROWS][NUM_COLS],(*p)[NUM_COLS], i;
for (p = &a[0],i=0; p < &a[NUM_ROWS]; p++,i++){
(*p)[i]=i;
}
printf("The value of a[0][0] is %d\n",a[0][0]); // I want 0
printf("The value of a[0][1] is %d\n",a[0][1]); // 1
printf("The value of a[0][2] is %d\n",a[0][2]); // 2
printf("The value of a[0][3] is %d\n",a[0][3]); // 3
printf("The value of a[0][4] is %d\n",a[0][4]); // 4
return 0;
}
Hi guys I'm a C novice, and I am trying to understand processing the columns of a 2D array.
I wanted output of 0,1,2,3,4 from row 0's columns but I had these results
The value of a[0][0] is 0
The value of a[0][1] is 0
The value of a[0][2] is 1
The value of a[0][3] is 0
The value of a[0][4] is -1
I tried to find what was wrong, but I failed to....
I will be grateful if someone explains what is wrong with my codes..
Your assignment in the loop is initializing the leading diagonal:
(*p)[i] = i;
To illustrate, here's an adaptation of your code that prints the whole matrix (and initializes it):
#include <stdio.h>
#include <string.h>
#define NUM_ROWS 3
#define NUM_COLS 5
int main(void)
{
int a[NUM_ROWS][NUM_COLS], (*p)[NUM_COLS], i;
/* Set all elements to -1 assuming 2's complement */
memset(a, 0xFF, sizeof(a));
for (p = &a[0], i = 0; p < &a[NUM_ROWS]; p++, i++)
{
(*p)[i] = i;
}
for (i = 0; i < NUM_ROWS; i++)
{
for (int j = 0; j < NUM_COLS; j++)
printf("%3d", a[i][j]);
putchar('\n');
}
return 0;
}
The output is:
0 -1 -1 -1 -1
-1 1 -1 -1 -1
-1 -1 2 -1 -1
Notice that the three elements on the leading diagonal are set to 0, 1, 2 and the rest are -1 as set by memset().
If you want to initialize the first row, then you simply use:
int (*p)[NUM_COLS] = &a[0];
for (int i = 0; i < NUM_COLS; i++)
(*p)[i] = i;
Or, more simply still, forget about p and use:
for (int i = 0; i < NUM_COLS; i++)
a[0][i] = i;
If you want to initialize column 0, you need:
(*p)[0] = i;
Or, again, more simply, forget about p and use:
for (int i = 0; i < NUM_ROWS; i++)
a[0][i] = i;
I think you want to write your for loop like this (based on you captions)
for the first row.
for (p = &a[0], i=0; i < NUM_COLS; i++){
(*p)[i] = i;
}
Here increasing the pointer p doesn't help for it will be incremented by a value of NUM_COLS every time due to pointer arithmetic.
Here is a second possible answer if you want to write and read the whole matrix within a single for loop
for (p = &a[0], i = 0; i < NUM_COLS * NUM_ROWS; i++) {
(*p)[i] = i;
}
Or the better solution would be to use two for loops as
for (p = &a[0], i = 0; p < &a[NUM_ROWS] ; p ++) {
int k = 0; //for the column count
for(;k < NUM_COLS; i++, k++) {
(*p)[k] = i;
}
}
Thanks for asking :)
for (p = &a[0]; p < &a[NUM_ROWS]; p++){
for(i=0;i<NUM_COLS;i++){
(*p)[i]=i;
printf("%d\n",(*p)[i]);
// I got 0 1 2 3 4 0 1 2 3 4 0 1 2 3 4
}
}
Should I write nested loop to print out all elements of 2D?
Is there a way to print out using 1 loop with processing columns of 2D array?
I want to output Yay if the matrix doesn't contain the same number on the same row or column otherwise output Nay
this is for my college homework. I already tried to check the column and row in the same loop but the output still not right
#include <stdio.h>
int main()
{
int size;
int flag;
scanf("%d",&size);
char matrix[size][size];
for (int i = 0; i < size; i++)
{
for (int l = 0; l < size; l++)
{
scanf("%s",&matrix[i]);
}
}
for (int j = 0; j < size; j++){
for (int k = 0; k < size; k++){
if(matrix[j] == matrix[j+1] || matrix[j][k]==matrix[j][k+1])
{
flag = 1;
}
else
{
flag = 0;
}
}
}
if (flag == 1)
{
printf("Nay\n");
}
else
{
printf("Yay\n");
}
return 0;
}
I expect to output "Nay" when I input
3
1 2 3
1 2 3
2 1 3
and "Yay" when i input
3
1 2 3
2 3 1
3 1 2
Your matrix is a 2D array and you are referencing it using only a single subscript matrix[index] at several places which returns the address of the row. Index it using both the row and column indices. Try the code below:
{
int size;
int flag;
scanf("%d",&size);
char matrix[size][size];
for (int i = 0; i < size; i++)
{
for (int l = 0; l < size; l++)
{
scanf("%s",&matrix[i][l]);
}
}
for(int j = 0; j < size; j++){
for (int k = 0; j < size; j++){
if(matrix[j][0]== matrix[j][k] || matrix[k][0]==matrix[k][j])
{
flag = 1;
break;
}
else
{
flag = 0;
}
}
}
if (flag == 1)
{
printf("Nay\n");
}
else
{
printf("Yay\n");
}
return 0;
}
Your have a logic problem. Your flag is reset on every element in the matrix and thus only reflects the result of the last check.
In addition, you need a break; in your nested loop. The logic is, if your flag becomes 1, you are sure to say Nay, and you don't want the flag to be reset to 0.
int flag = 0;
for (int i = 0; i != size && !flag; ++i) {
for (int j = 0; j != size; ++j) {
if ( /* detection */ ) {
flag = 1;
break;
}
}
}
if (flag)
printf("Nay\n");
else
printf("Yay\n");
Note: The commented /* detection */ part requires more work. Since it's your homework, you may try it first. You could use a hash table for memorization. Or brutal force to make the program simply work. It seems that your detection only checks for neighboring elements, which is not sufficient to assert that an element is unique in its row or column. Consider
1 2 1
3 4 5
6 7 8
I can't do your homework for you. The following is the brutal-force way you may consider.
The if ( /* detection */ ) part could be if (has_same_element(matrix, i, j)), with a function (pseudo code)
int has_same_element(matrix, row, col)
{
for each element a in matrix's row except matrix[row][col] itself
if (a == matrix[row][col])
return 1
for each element b in matrix's col except matrix[row][col] itself
if (b == matrix[row][col])
return 1
return 0
}
Of course there are smarter ways, like using a hash table, in which case you don't even need the nested loop. For the time being, work out a feasible solution, instead of the best solution.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I'm writing a Sudoku solution checker for a class and I've hit a wall.
I'm at the point where I'm checking if I can see whether or individual columns and rows are unique. For some reason the code works on 4x4 grids but as soon as I get up to a 5x5 grid or higher (goal is to get to a 9x9 grid) the program starts to print out that it had failed even when it should succeed.
Any help would be much needed, I want need a point in the right direction or where I should look into
Here's the code:
#include <stdio.h>
#include <stdlib.h>
int main ()
{
int i, j, n, k, p, q;
int fail;
int array[5][5];
int check[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
int a = 0;
char *output = NULL;
scanf("%d", &n);
// memory allocated for yes or no at end
output = malloc(sizeof(int) * (n));
while (a < n)
{
fail = 0;
// create this 2D array
for (i = 0; i < 5; i++)
{
for (j = 0; j < 5; j++)
{
scanf("%d", &(array[i][j]));
}
}
// seeing if row is unique
for (i = 0; i < 5; i++)
{
for (j = 0; j < 5; j++)
{
for (k = 0; k < 5; k++)
{
if (array[i][k] == array[i][k+1])
fail += 1;
}
}
}
// seeing if column is unique
for (i = 0; i < 5; i++)
{
for (j = 0; j < 5; j++)
{
for (k = 0; k < 5; k++)
{
if (array[k][j] == array[k+1][j])
fail += 1;
}
}
}
/* for (WHAT DO I DO FOR ROWS)
{
for (WHAT DO I DO FOR ROWS AGAIN BUT REPLACE ROWS WITH COLUMNS)
{
for (NOW IM LOST)
}
}
*/
// success or failure? 0 success, 1 failure
if (fail >= 1)
output[a] = 1;
else
output[a] = 0;
a++;
}
// print out yah or nah
for (i = 0; i < n; i++)
{
if (output[i] == 0)
printf("YES\n");
else
printf("NO\n");
}
return 0;
}
Forget my for loop for the grids, I'll work on that once I figure out how to get the columns and rows working correctly.
Thanks for the help!
Here is an input that would cause the program to fail when it should succeed
1
1 2 3 4 5
2 3 4 5 1
3 4 5 1 2
4 5 1 2 3
5 1 2 3 4
output would be
NO
EDIT: It is now working with a 9x9 grid! Thanks for the help!
#include <stdio.h>
#include <stdlib.h>
#define SIDE_LENGTH 9
int main ()
{
int i, j, n, k, p, q;
int fail;
int array[SIDE_LENGTH][SIDE_LENGTH];
int check[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
int a = 0;
char *output = NULL;
scanf("%d", &n);
// memory allocated for yes or no at end
output = malloc(sizeof(int) * (n));
while (a < n)
{
fail = 0;
// create this 2D array
for (i = 0; i < SIDE_LENGTH; i++)
{
for (j = 0; j < SIDE_LENGTH; j++)
{
scanf("%d", &(array[i][j]));
}
}
// seeing if row is unique
for (i = 0; i < SIDE_LENGTH; i++)
{
for (j = 0; j < SIDE_LENGTH; j++)
{
for (k = 0; k < SIDE_LENGTH - 1; k++)
{
if (array[i][k] == array[i][k+1])
fail += 1;
}
}
}
// seeing if column is unique
for (i = 0; i < SIDE_LENGTH; i++)
{
for (j = 0; j < SIDE_LENGTH; j++)
{
for (k = 0; k < SIDE_LENGTH - 1; k++)
{
if (array[k][j] == array[k+1][j])
fail += 1;
}
}
}
/* for (WHAT DO I DO FOR ROWS)
{
for (WHAT DO I DO FOR ROWS AGAIN BUT REPLACE ROWS WITH COLUMNS)
{
for (NOW IM LOST)
}
}
*/
// success or failure? 0 success, 1 failure
if (fail >= 1)
output[a] = 1;
else
output[a] = 0;
a++;
}
// print out yah or nah
for (i = 0; i < n; i++)
{
if (output[i] == 0)
printf("YES\n");
else
printf("NO\n");
}
return 0;
}
input:
1
1 2 3 4 5 6 7 8 9
2 3 4 5 6 7 8 9 1
3 4 5 6 7 8 9 1 2
4 5 6 7 8 9 1 2 3
5 6 7 8 9 1 2 3 4
6 7 8 9 1 2 3 4 5
7 8 9 1 2 3 4 5 6
8 9 1 2 3 4 5 6 7
9 1 2 3 4 5 6 7 8
#ameyCU helped find the error in my code
Setting k to one less than what i and j were set to allowed the code to successfully run on any X*X sized grid. Because k is one less than i and j, it won't try to access a part of the array that hasn't been allocated yet which is where my problem lied.
for (i = 0; i < 5; i++)
{
for (j = 0; j < 5; j++)
{
for (k = 0; k < 5; k++)
{
if (array[i][k] == array[i][k+1])
fail += 1;
}
}
}
Despite the overwriting of the array as already pointed out, your logic is flawed. You don't use j at all. You are just comparing the same values five times.
The problem is the comparison.
if (array[i][k] == array[i][k+1])
I think you are using i as row and column index, then using j to iterate for duplicates. k will be what you compare against so ...
/* compare if j'th value is same as k'th value */
if (j != k && array[i][j] == array[i][k]) /* Don't check same against same */
the second comparison should be
/* compare if j'th value is same as k'th value */
if (j != k && array[j][i] == array[k][i]) /* Don't check same against same */
That would fix your overflow (k+1) bug, and get you going.
The squares could be fixed with
struct co_ords {
int x;
int y;
};
struct co_ords boxes[][9] = {{ {0,0}, {0,1}, {0,2},
{1,0}, {1,1}, {1,2},
{2,0}, {2,1}, {2,2}
},
{ {3,0}, {3,1}, {3,2},
{4,0}, {4,1}, {4,2},
{5,0}, {5,1}, {5,2} },
... /* more boxes go here */
{ {6,6}, {6,7}, {6,8},
{7,6}, {7,7}, {7,8},
{8,6}, {8,7}, {8,8} }};
for( i = 0; i < 9; i++ ){
struct co_ords current_box * = boxes[i];
for( j = 0; j < 9; j++ ) {
for( k = 0; k < 9; k++ ){
if( j != k && array[ current_box[j].x ][ current_box[j].y] == array[ current_box[k].x ][ current_box[k].y] )
fail += 1;
}
}
}
int array[5][5];
so the array is allocated as 5x5
for (i = 0; i < 5; i++)
{
for (j = 0; j < 5; j++)
{
scanf("%d", &(array[i][j]));
}
}
and you are indexing from 0 to 5 ..
to use larger, please do replace all those "5"s with a precompiler definition.
#define SUDOKU_SIDE_LENGTH 5
...
int array[SUDOKU_SIDE_LENGTH ][SUDOKU_SIDE_LENGTH ];
...
for (i = 0; i < SUDOKU_SIDE_LENGTH ; i++)
{
for (j = 0; j < SUDOKU_SIDE_LENGTH ; j++)
{
scanf("%d", &(array[i][j]));
}
}
etc.. that will ensure that you always allocate enough space for the array.
adjust size on the definition, not in the code..
I have file that has 30 matrices and each matrix has unknown size of rows and columns(with a max size of 1000). For instance:
0 5 2
5 0 2
1 6 0
0 9 7 4
3 0 9 1
9 1 0 4
9 4 1 0
I need to read each matrix into a 2d array. What would be the most efficient way of doing this?
This is what I have so far:
int** mat=malloc(1000000*sizeof(int*));
for(i=0;i<1000000;++i)
mat[i]=malloc(4*sizeof(int));
while(!feof(file))
{
for(i=0;i<1000;i++)
{
for(j=0;j<1000;j++){
fscanf(file,"%d%*[^\n]%*c",&mat[i][j]);
printf("%d\n", mat[i][j]);
}
}
}
Well the most efficient way is definitely not that. First figure out how big an array you need, then allocate it.
Apparently some matrices are small, so there is no need to allocate the maximum size 1000x1000. One way is to put the matrix in a structure to make it easier to keep track of size:
struct s_matrix
{
int **matrix;
int N; //one side of the square matrix N x N
};
typedef struct s_matrix Matrix;
Then allocate and free the matrix
void allocate_matrix(Matrix *m, int N)
{
m->N = N;
m->matrix = (int**)malloc(N * sizeof(int*));
*m->matrix = (int*)malloc(N * N * sizeof(int));
for (int i = 0; i < N; i++)
m->matrix[i] = *m->matrix + i * N;
for (int i = 0; i < N; i++)
for (int j = 0; j < N; j++)
m->matrix[i][j] = 0;
}
void free_matrix(Matrix *m)
{
if (!m) return;
if (!m->matrix) return;
free(*m->matrix);
free(m->matrix);
}
Now we can declare how many matrices we need. It looks like this number is fixed at 30, so I don't think we need dynamic allocation.
int main()
{
const int max_count = 30;
Matrix list[max_count];
for (int i = 0; i < max_count; i++)
list[i].matrix = NULL;
allocate_matrix(&list[0], 3);//allocate 3x3 matrix
allocate_matrix(&list[1], 1000);//1000x1000
allocate_matrix(&list[2], 4000);//4000x4000
int **m;
m = list[0].matrix;
m[0][0] = 0;
m[0][1] = 1;
m[0][2] = 2;
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++)
printf("%02d %s", m[i][j], (j == 2) ? "\n" : "");
//...
for (int i = 0; i < max_count; i++)
free_matrix(&list[i]);
printf("hey it worked, or maybe it didn't, or it did but there is memory leak\n");
return 0;
}
I'm currently learning C programming, to better my understanding of matrices in C I've tried to make this program.
I seem to be having problems with the output, as you can see the program has 3 functions.
The first one allows you to input the values for the array and then displays it. The second function performs the multiplication and the last should display the output of the multiplied matrix.
However the output is strange. Here is my code. The output is just below the code.
#include <stdio.h>
void read_matrix(int m2[][3] )
{
int i, j;
printf("input values for matrix in order of rows first \n");
for (i = 0; i < 3; i++)
{
for (j = 0; j < 3; j++)
{
scanf("%d",&m2[i][j]);
}
}
for (i = 0; i < 3; i++)
{
for (j = 0; j < 3; j++)
{
printf("%d ", m2[i][j]);
}
printf("\n");
}
}
void multiply_matrices(int m1[][3], int m2[][3] ,int m3[][3])
{
int i, j, k;
for (i = 0; i < 3; i++){
for (j = 0; j < 3; j++){
for (k = 0; k < 3; k++){
m3[i][j] +=m1[i][k]*m2[k][j];
}
}
}
}
void write_matrix(int m3[][3] )
{
int i, j;
for (i = 0; i < 3; i++)
{
for (j = 0; j < 3; j++)
{
printf("%d ", m3[i][j]);
}
printf("\n");
}
}
int main(void)
{
int matrix1[3][3], matrix2[3][3], matrix3[3][3];
read_matrix(matrix1);
read_matrix(matrix2);
multiply_matrices(matrix1, matrix2, matrix3);
write_matrix(matrix3);
return 0;
}
and this is the output!
input values for matrix in order of rows first
1
2
3
2
2
2
1
2
2
1 2 3
2 2 2
1 2 2
input values for matrix in order of rows first
2
1
1
1
2
1
2
1
2
2 1 1
1 2 1
2 1 2
-858993450 -858993452 -858993451 /*This is the multiplied matrix output!*/
-858993450 -858993452 -858993452
-858993452 -858993453 -858993453
Press any key to continue . . .
I fear it may be just a silly mistake; if so I'm sorry, but I can't see where I am going wrong at this moment.
Any help would be greatly appreciated.
You need to initialize all elements of matrix m3 to 0 before performing this operation
m3[i][j] +=m1[i][k]*m2[k][j];
in function multiply_matrices.
Initialize matrix3 in the function multiply matrix like this
for (int i=0;i<3;i++)
{
for (int j=0;j<3;j++)
{
m3[i][j]=0;
}
}
After this, do the multiplication and everything will work perfectly.
int m3[][]={};
It initially stores 0 for all available index of m3