I want my matrix to look the following:
1 2 3
X X X
X X X
When X is a random number.
I tried the following:
void initMat(int *mat, int rows, int cols)
{
*(mat + 0) = 1;
*(mat + 1) = 2;
*(mat + 2) = 3;
for (int i = 0; i < rows * cols - 3; i++)
{
*(mat + 3) = rand() % 6;
mat++;
}
}
and I call the function:
initMat((int *)startValues, 3, 3);
When I print my matrix with the following function:
void printMat(const int *mat, int rows, int cols)
{
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
printf("%4d", *mat);
mat++;
printf(" ");
}
printf("\n");
}
}
I get something that look like 2D array, as I actually wanted, for example:
startValues:
1 2 3
4 1 5
4 4 5
But when I try to print it with (In the same main, after the matrix was initiated)
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
printf("%4d", startValues[i][j]);
}
printf("\n");
}
I get:
VALUES:
1 2 3
3 4 1
1 5 2
Why does it happen? Why the values are different and some look the same. How should I reach each value? I tried also using the formula:
m+ cols*i + j //(in my case startValues + 3*i+j in the last loop)
But it gives me very large random numbers and I'm not really sure when do I need to use it instead of mat[i][j].
I suggest using pointer to Variable-Length Array (VLA). It makes code far more readable:
void initMat(int rows, int cols, int mat[static rows][cols])
{
mat[0][1] = 1;
mat[0][2] = 1;
mat[0][3] = 1;
for (int r = 1; r < rows; r++)
for (int c = 0; c < cols; c++)
mat[r][c] = rand() % 6;
}
Related
I need to delete (not skip while printing) the rows and columns of a matrix that appear more than once in program, and I should print only first row from the top that appears more than once or the first column from the left that appears more than once.
Example input:
1 2 3 2
4 5 6 5
1 2 3 2
7 8 9 8
After deleting:
1 2 3
4 5 6
7 8 9
Here's my code:
#include <stdio.h>
int main() {
int i, j, m, n,row,col, mat[200][200];
scanf("%d %d", &m, &n);
row = m; col = n;
for (i = 0; i < m; i++)
for (j = 0; j < m; j++)
scanf("%d", &mat[i][j]);
for (i = 0; i < m; i++)
for (j = 0; j < m; j++) {
if (mat[i][j] == mat[i++][j++])
row--;
if (mat[j][i] == mat[j++][i++])
col--;
}
for (i = 0; i < row; i++) {
for (j = 0; j < col; j++) {
printf("%d ", mat[i][j]);
}
printf("\n");
}
return 0;
}
Do you have any idea how to make the algorithm work for this task? Mine has mistakes.
Would you please try the following:
#include <stdio.h>
#define ROWS 200
#define COLS 200
#define TRUE 1
#define FALSE 0
/*
* delete k'th row from the m x n matrix
*/
void deleterow(int mat[ROWS][COLS], int m, int n, int k)
{
int i, j;
for (i = k; i < m - 1; i++) {
for (j = 0; j < n; j++) {
mat[i][j] = mat[i + 1][j];
}
}
}
/*
* delete k'th columns from the m x n matrix
*/
void deletecol(int mat[ROWS][COLS], int m, int n, int k)
{
int i, j;
for (j = k; j < n - 1; j++) {
for (i = 0; i < m; i++) {
mat[i][j] = mat[i][j + 1];
}
}
}
int main() {
int i, j, m, n,row,col, mat[ROWS][COLS];
int iref, jref; // reference indexes to compare
int match; // flag to show if the row/col duplicates
// read input matrix
scanf("%d %d", &m, &n);
row = m; col = n;
for (i = 0; i < m; i++)
for (j = 0; j < n; j++)
scanf("%d", &mat[i][j]);
// examine row by row
for (iref = 0; iref < m; iref++) {
// compare rows below iref and remove the row if duplicates
for (i = iref + 1; i < m; i++) {
match = TRUE;
for (j = 0; j < n; j++) {
if (mat[i][j] != mat[iref][j]) {
match = FALSE;
break;
}
}
if (match) {
deleterow(mat, m, n, i);
m--;
}
}
}
// examine column by column
for (jref = 0; jref < n; jref++) {
// compare columns more right than jref and remove the col if duplicates
for (j = jref + 1; j < n; j++) {
match = TRUE;
for (i = 0; i < m; i++) {
if (mat[i][j] != mat[i][jref]) {
match = FALSE;
break;
}
}
if (match) {
deletecol(mat, m, n, j);
n--;
}
}
}
// see the result
for (i = 0; i < m; i++) {
for (j = 0; j < n; j++) {
printf("%2d%s", mat[i][j], j == n - 1 ? "\n" : " ");
}
}
return 0;
}
Output with the provided example:
1 2 3
4 5 6
7 8 9
[Explanation]
As for the operations of rows:
First, focus on the top row as a "reference". The row is indexed by
the variable iref which is assigned to 0 at first.
Then compare the remaining rows with the reference, changing
the row index i from iref+1 (just below the reference row) to n-1
(the bottom row).
If a row duplicates with the reference, remove the row with the
deleterow() function and decrement the row size m by one.
The modification of m affects the for loops which compare the
loop variables with m, meaning the matrix size is updated immediately.
This is a preferable nature of the for loop (IMHO).
If the comparizon reaches the bottom row, increment iref and repeat
the comparisons again.
Finally every row has been compared to each other and the duplicates have
been deleted.
Then perform the similar operations with columns.
#include <stdio.h>
#include <stdlib.h>
#define col 3
#define row 3
#define MIN 200
#define MAX 600
int main()
{
int Matriz[col][row] = {0};
int i, j;
int choose;
int sum = 0;
for (i = 0; i < row; i++) // primeira matriz com valores randomicos
{
for (j = 0; j < col; j++)
{
Matriz[row][col] = MIN + (rand() % (MAX - MIN + 1));
printf("%5d", Matriz[row][col]);
}
printf("\n");
}
for (i = 0; i < row; i++)
{
sum = sum + Matriz[i][i];
}
printf("%d", sum);
}
// my code prints the sum of the diagonals as 0 that's my question, what did i do wrong? i'm sorry its my first time using stackoverflow kinda confuse also
In your code
for (j = 0; j < col; j++)
{
Matriz[row][col] = MIN + (rand() % (MAX - MIN + 1));
printf("%5d", Matriz[row][col]);
}
row and col are not counters, use i and j, respectively.
Moreover, by using row (3) and col (3) as indexes, you're off-by-one, as C uses 0-based array indexing. Thus, it invokes undefined behavior in your code.
You only set one element in you matrix:
Matriz[row][col] = ... should be Matriz[i][j] = ...
I need to change the matrix columns into rows after a given number N. For example if N = 3 then the row is n * 2 given in this exercise. Now after the 3rd column every other column needs to be a row. I know how to transpose a matrix but I get confused how to do it after given N.
Code:
#include <stdio.h>
int main() {
int n;
int a[n][n * 2];
int b[n * 2][n];
scanf("%d", &n);
for(int i = 0;i < n; i++) {
for(int j = 0; j < n * 2; j++) {
scanf("%d", a[i][j]);
}
}
for(int i = 0; i < n * 2; i++) {
for(int j = 0; j < n; j++) {
a[i][j] = b[j][i];
}
}
return 0;
}
Example for n = 3.
1 2 3 4 5 6
7 8 9 10 11 12
13 14 15 16 17 18
I need to achieve
1 2 3
7 8 9
13 14 15
4 5 6
10 11 12
16 17 18
First square of the matrix (array) is left unchanged, so both arrays have the same starting. Later part is shifted n units left and n units down, so the following code should help you to solve the problem:
for(int i = 0; i < n; i++) {
for(int j = 0; j < n; j++) {
b[i][j] = a[i][j];
}
}
for(int i = 0; i < n; i++) {
for(int j = 0; j < n; j++) {
b[i + n][j] = a[i][j + n];
}
}
As both set of for loops have the same kind of variable changes, we can converge them into one, as #Chris Turner did.
The whole code should look something like this:
#include <stdio.h>
int main() {
int n;
scanf("%d", &n);
int a[n][n * 2];
int b[n * 2][n];
for(int i = 0;i < n; i++) {
for(int j = 0; j < n * 2; j++) {
scanf("%d", &a[i][j]);
}
}
for(int i = 0; i < n; i++) {
for(int j = 0; j < n; j++) {
b[i][j] = a[i][j];
b[i + n][j] = a[i][j + n];
}
}
return 0;
}
Firstly you need to initialise n before you use it. In the code below, n has no defined value, so using it to define the size of your arrays leads to undefined behaviour.
int n;
int a[n][n * 2];
int b[n * 2][n];
You can move the array definitions until after you've set n
Secondly, when using scanf to read in an int you have to pass in a pointer to the variable, so this line is wrong and your compiler should be throwing up warnings about it
scanf("%d", a[i][j]);
it should be
scanf("%d", &a[i][j]);
if you want to copy from a into b you need to do it the right way around
you've got which is copying from b to a and also goes out of bounds as i goes up to n*2 and a's first index is just n.
a[i][j] = b[j][i]
what you want is just this.
b[i][j] = a[j][i]
But that doesn't solve your problem as that is just transposing and you're trying to split the matrix in half and stack it differently. So to start with you need to copy the first n by n elements from a to b like this.
for(int i = 0; i < n; i++) {
for(int j = 0; j < n; j++) {
b[i][j] = a[i][j];
and then to copy the second chunk you can use the same loops and offset by n
b[i+n][j] = a[i][j+n];
After all these changes your code should look like this:
#include <stdio.h>
int main() {
int n;
scanf("%d", &n);
int a[n][n * 2];
int b[n * 2][n];
for(int i = 0;i < n; i++) {
for(int j = 0; j < n * 2; j++) {
scanf("%d", &a[i][j]);
}
}
for(int i = 0; i < n; i++) {
for(int j = 0; j < n; j++) {
b[i][j] = a[i][j];
b[i+n][j] = a[i][j+n];
}
}
return 0;
}
I've written a code that takes elements from the user for a 2-d matrix and then prints using the base address of matrix.
for simplicity i've omitted the inputting part .
Here's the code that I've tried:-
main()
{
int mat[50][50],i, j, r, c, *p;
p = &mat[0][0];
<------skip the input---->
for(i = 0; i < r; i++) /* print the matrix*/
{
for(j = 0; j < c; j++)
{
printf("%d\t", *((p + i) + j));
}
printf("\n");
}
}
Input:
1
2
3
4
Output:
1 2
2 0
looks like my code is wrong. plz help.Really confused!!!
Basically what you want to print is p[i][j] which is equivalent to *(p + (i*rowNum) + j). This can be as shown below.
printf("%d\t", *(p + (c * i) + j);
are you sure you want to do it with pointers ?
Here is a simpler solution:
int matrix[SIZE][SIZE] = { {1, 2}, {3, 4} };
for (int row = 0; row < SIZE; row++)
{
for (int col = 0; col < SIZE; col++)
{
printf("%d\t", matrix[row][col]);
}
printf("\n");
}
I don't understand what x[i][j] = -i*cols - j ; is exactly doing.. Can someone explain because i am beginner. I cant understand pointers '*'. Sorry for bad English.
int main(int argc, char *argv[]) {
int a[5][5];
readarray(5, 5, a);
printarray(3, 5, a);
return 0;
}
void readarray(int rows, int cols, int x[rows][cols]) {
int i, j;
for (i = 0; i< rows; i++)
for (j = 0; j < cols; j++)
x[i][j] = -i*cols - j ;
}
void printarray(int rows, int cols, int x[rows][cols]) {
int i, j;
for (i = 0; i< rows; i++) {
for (j = 0; j < cols; j++)
printf("%4d", x[i][j]) ;
printf("\n");
}
}
* here is for the multiplication, not pointers.
x[i][j] = -i*cols - j ;
There are several things happen here:
negative: -i
multiplication: (-i) * cols
substraction: - j
assignment: assign the result of the right side to x[i][j].
Check out this thread if you want to know the difference between using * for dereference and multiplication.
That is just populating the values of the array elements.
x[i][j] = -i*cols - j ; = x[i][j] = -i*5 - j ;
x[0][0] = 0
x[0][1] = -0*5 - 1 = -1
. . .
x[1][0] = -1*5 - 0 = -5
. .
x[3][3] = -3*5 - 3 = -18
and so on..
I think only one multiplication is being performed. No pointers are being used.
i=2;
j=5;
cols = 5;
x[2][5] = -2 * 5 - 5