I wrote a simple code to create a Directed Graph using adjacency matrix with randomly generated numbers that are the vertices of the graph. But my task is to make a bigger matrix with 1000 rows and columns. My code cannot make more than a 50*50 matrix. How can I make a big matrix?
This is the code that I have created.
int arr[1001][1001];
int main()
{
int i,a,b,j,k,m,n;
scanf("%d%d",&a,&b);
for(i=0;i<b;i++)
{
m=rand()%100;
n=rand()%100;
arr[m-1][n-1]=1;
}
for(j=0;j<a;j++)
{
for(k=0;k<a;k++)
{
printf("%d ",arr[j][k]);
}
printf("\n");
}
The compiler doesn't give any output.
You could also create a flat array like this:
#define MATR(arr, column, row) (arr + column + row*101)
int* arr = (int*)malloc(101*101*sizeof(int));
*MATR(arr, 1, 2) = 123;
Then you only need one malloc/free.
The solution I propose you doesn't use an array of pointers to pointer, it uses only a vector managed as an array by means some #define. In this way the code will be generated might be faster.
With the vector solution you will need to free only a vector, with the solution with pointers to pointer you will need to free all columns pointers and then the "rows" pointer.
Into the code I've set to 1 only the array elements comprised in the interval you set with the variable a, otherwise the output might show only elements containing 0.
#include <stdio.h>
#define ROWS 1000
#define COLS 1000
#define ARRAY(m,n) [n+m*COLS]
int main()
{
int i,a,b,j,k,m,n;
int * arr = malloc(COLS*ROWS*sizeof(*arr));
if (arr) {
scanf("%d %d",&a,&b);
for(i=0;i<b;i++)
{
// m=rand()%ROWS; // to set into the full array
m=rand()%a;
// m=i; to have a diagonal
// n=rand()%COLS; // to set into the full array
n=rand()%a;
// n=i; to have a diagonal
arr ARRAY(m,n)=1;
}
for(j=0;j<a;j++)
{
for(k=0;k<a;k++)
{
printf("%d ",arr ARRAY(j,k));
}
printf("\n");
}
free(arr);
} else {
perror("malloc: ");
return 1;
}
return 0;
}
Notes:
C uses, as first element of arrays, the indexes couple (0,0) not (1,1).
The instruction m=rand()%x generates numbers from 0 to x-1.
You are only printing an a*a matrix.
As previously seen you will need dynamic memory allocation.
So, you can allocate an a*a matrix and do not need to allocate the 1001 * 1001 matrix.
The setting of 1's has been modified to stop out of bounds error and index of -1
Memory allocation call of calloc is used to initialze the matrix to zero.
Modified code is below.
int main(void)
{
int **arr;
int i,a,b,j,k,m,n;
scanf("%d%d",&a,&b);
arr = malloc (sizeof(int*) * a);
for (i=0; i<a; i++)
{
arr[i] = calloc(a,sizeof(int));
}
for(i=0;i<b;i++)
{
m=rand()%a;
n=rand()%a;
arr[m][n]=1;
}
for(j=0;j<a;j++)
{
for(k=0;k<a;k++)
{
printf("%d ",arr[j][k]);
}
printf("\n");
}
return 0;
}
You declare your array like this: int arr[1001][1001]; This is perfectly fine as long as you don't put it on the stack. Since you declare it globaly, everything should be OK.
But the way you use the array is not OK:
m=rand()%100;
n=rand()%100;
arr[m-1][n-1]=1;
Here m and n will have values in the range 0...99. When both m and n are zero, your array asignement will turn into this:
arr[-1][-1]=1;
And you will get undefined behaviour.
Probably (depending on your use case), the asignement should look like this
arr[m][n] = 1;
For a heap based array, see below.
int main()
{
int i,a,b,j,k,m,n;
scanf("%d%d",&a,&b);
int** arr = (int**)malloc(1001*sizeof(int*));
for(i=0;i<1001;++i)
arr[i]=(int*)malloc(1001*sizeof(int));
for(i=0;i<b;i++)
{
m=rand()%100;
n=rand()%100;
arr[m-1][n-1]=1;
}
for(j=0;j<a;j++)
{
for(k=0;k<a;k++)
{
printf("%d ",arr[j][k]);
}
printf("\n");
}
// memory not freed since the program is ending anyway. In real programs, use free to free the 102 arrays.
}
I am successfully storing the calculated subsets in a 2-D array matrix in C language.Now I want to print the subsets in an order desired.
For eg.
2-D array matrix is
10 7 3 2 1
10 7 5 1
7 6 5 3 2
10 6 5 2
10 7 6
Desired Output
10 7 6
10 7 5 1
10 7 3 2 1
10 6 5 2
7 6 5 3 2
How quick sort can be applied to sort/order these rows?
As #chqrlie noted, this can be easily solved with qsort.
Depending on the way the matrix is declared (is it an array of pointers to arrays of ints? do all arrays have the same length? is it a global array of fixed size?) the code will have to do slightly different things.
So, assuming the array is a global variable and all rows have same length (padded with 0s):
MWE:
#include <stdio.h>
#include <stdlib.h>
/*
Compare 2 integers
returns:
-1 if *i1 < *i2
+1 if *i1 > *i2
0 if *i1 == *i2
*/
int intcmp(const int *i1, const int *i2)
{
return (*i2 < *i1) - (*i1 < *i2);
}
#define ROWS 5
#define COLS 5
/*
Assumes rows already sorted in descending order
NOTE: qsort calls the comparison function with pointers to elements
so this function has to be tweaked in case the matrix is an array of
pointers. In that case the function's declaration would be:
int rowcmp(int **pr1, int **pr2)
{
const int *r1 = *pr1;
const int *r2 = *pr2;
// the rest is the same
}
*/
int rowcmp(const int *r1, const int *r2)
{
int i = 0, cmp;
do {
cmp = intcmp(&r1[i], &r2[i]);
i++;
} while (i < COLS && cmp == 0);
return -cmp; /* return -cmp to sort in descending order */
}
int data[5][5] = {
{10,7,3,2,1},
{10,7,5,1,0},
{ 7,6,5,3,2},
{10,6,5,2,0},
{10,7,6,0,0}
};
void printmatrix()
{
int i, j;
for (i = 0; i < ROWS; i++) {
for (j = 0; j < COLS; j++) {
printf("%d ", data[i][j]); /* leaves a trailing space in each row */
}
printf("\n");
}
}
int main()
{
printmatrix();
qsort(data, 5, sizeof(data[0]), (int (*)(const void *, const void *))rowcmp);
printf("\n");
printmatrix();
return 0;
}
For the most flexible solution, I would define
struct row {
size_t len;
int *elems;
};
struct matrix {
struct row *rows;
size_t nrows;
};
and change the code accordingly.
NOTE: code not thoroughly tested, use with caution ;)
First of all, are you sure that the 1 on row 3,col 5 should be there and not on the last line?
Anyway, an efficient way to achieve what you want is:
compute the frequency array
declare a new matrix
go from the highest element (10 in your case) from frequency array and put in your matrix using your desired format.
It is time-efficient because you don't use any sorting algorithm, thus you don't waste time there.
It is NOT space-efficient because you use 2 matrices and 1 array, instead of only 1 matrix as suggested in other posts, but this should not be a problem, unless you use matrices of millions of rows and columns
C code for frequency array:
int freq[11] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
for(int i=0; i<NO_ROWS; i++) {
for(int j=0; j<NO_COLS; j++) {
if(MATRIX[i][j]!=null && MATRIX[i][j]>0 && MATRIX[i][j]<11) {
freq[MATRIX[i][j]]++;
}
}
}
C code for computing the new matrix dimensions
(assuming you want to keep the number of rows)
OUTPUT_MATRIX[100][100] /*I declared it statically, but I would advise to make it dinamically */
/* first, compute the number columns.
To do so, we need the number of elements
(we get them by simply summing up frequency array's elements) */
int s=0;
for(int i=0; i<11; i++) {
s+=frequency[i];
}
int addOne = 0 /* boolean value to check if we will have to add one extra column for safety */
if(s % NO_ROWS) {
addOne = 1; /* division is not even, so we will have to add extra column */
}
NO_COLS = s/NO_ROWS + addOne;
Now, final part, assigning the values from frequency array to the OUTPUT_MATRIX
int k=0;
int currentNumber = 10; /* assigning starts from 10 */
for(int i=0; i<NO_ROWS; i++) {
for(int j=0; j<NO_COLS; j++) {
if(currentNumber>0) {
if(frequency[currentNumber]==0 || k>=frequency[currentNumber]) {
currentNumber--;
k=0;
}
OUTPUT_MATRIX[i][j] = frequency[currentNumber];
k++;
} else {/*here, you can assign the rest of the value with whatever you want
I will just put 0's */
OUTPUTMATRIX[i][j] = 0;
}
}
}
Hope this helps!
This is what I do in C++ to reorder a matrix:
// b is the matrix and p is an array of integer containing the desired order of rows
for(i=0; i<n; i++){
if( p[i]==i )
continue;
b[i].swap(b[p[i]]);
j = p[i]; // New row i position
// Update row i position to new one
for(int k=i+1; k<n; k++){
if( p[k] == i )
p[k] = j;
}
printRow( b[i] );
}
You need to define an array of pointers of the data type you use and then you can reorder your matrix.
for example your matrix is: arr[5][10], and you want to print line 4 before line 3:
int *[5] arr2;
arr2[0] = &arr[0][0];
arr2[1] = &arr[1][0];
arr2[2] = &arr[2][0];
arr2[3] = &arr[4][0];
arr2[4] = &arr[3][0];
in regard to how will the ordering algorithm work, i would suggest placing a header in the start of each array in the matrix which will tell you how many elements it has(basically the first element of each array can be a counter of the total elements) afterwards you can order the strings by comparing the header, and if it is equal comparing the first element and so on. this can be done in a loop that iterates as many times as there are elements in the array, when the elements are not equal, break out of the loop.
hope this helps.
I have two arrays. Array A and Array B. Now I need to get where in array B is sequence from array A located. I need to get location of last number and I don't know how.
A[4]={6,3,3,2};
B[10][18]={
{5,3,6,5,6,1,6,1,4,4,5,4,4,6,3,3,1,3},
{6,2,3,6,3,3,2,4,3,1,5,5,3,4,4,1,6,5},
{6,4,3,1,6,2,2,5,3,4,3,2,6,4,5,5,1,4},
{5,3,5,6,6,4,3,2,6,5,1,2,5,6,5,2,3,1},
{1,2,5,2,6,3,1,5,4,6,4,4,4,2,2,2,3,3},
{4,1,4,2,3,2,3,6,4,1,6,2,3,4,4,1,1,4},
{5,3,3,2,6,2,5,2,3,1,2,6,5,1,6,4,1,3},
{4,5,2,1,2,5,2,6,4,3,3,2,3,3,3,1,5,1},
{1,3,5,5,2,1,3,3,3,1,3,3,6,3,3,3,6,5},
{4,5,2,4,2,3,4,2,5,6,5,2,6,3,5,4,5,2}
};
For example: Sequence 6,3,3,2 start in second row and in forth column and ends in seventh column. I need to get location of number 2. My result should be:
Row = 2,
Column= 7
Sequence isn't always in row. It can be in column to. For example:
3,2,4,3 and I ned to know location of number 4.
I know how to search one number in one dimensional array but in this case I don't have solution.
Language is C.
You can compare blocks using memcmp:
for (i = 0; i < rows; i++) { /* For each row */
for (j = 0; j < cols - size; j++) { /* For each col until cols - 4 */
if (memcmp(A, &B[i][j], sizeof(A)) == 0) { /* Compare entire block */
#include <stdio.h>
#include <string.h>
int main(void)
{
int A[4] = {6,3,3,2};
int B[10][18] = {
{5,3,6,5,6,1,6,1,4,4,5,4,4,6,3,3,1,3},
{6,2,3,6,3,3,2,4,3,1,5,5,3,4,4,1,6,5},
{6,4,3,1,6,2,2,5,3,4,3,2,6,4,5,5,1,4},
{5,3,5,6,6,4,3,2,6,5,1,2,5,6,5,2,3,1},
{1,2,5,2,6,3,1,5,4,6,4,4,4,2,2,2,3,3},
{4,1,4,2,3,2,3,6,4,1,6,2,3,4,4,1,1,4},
{5,3,3,2,6,2,5,2,3,1,2,6,5,1,6,4,1,3},
{4,5,2,1,2,5,2,6,4,3,3,2,3,3,3,1,5,1},
{1,3,5,5,2,1,3,3,3,1,3,3,6,3,3,3,6,5},
{4,5,2,4,2,3,4,2,5,6,5,2,6,3,5,4,5,2}
};
size_t i, j, size, rows, cols;
int founded = 0;
size = sizeof(A) / sizeof(A[0]);
rows = sizeof(B) / sizeof(B[0]);
cols = sizeof(B[0]) / sizeof(B[0][0]);
for (i = 0; i < rows; i++) {
for (j = 0; j < cols - size; j++) {
if (memcmp(A, &B[i][j], sizeof(A)) == 0) {
founded = 1;
break;
}
}
if (founded) break;
}
if (founded) printf("Row: %zu Col: %zu\n", i + 1, j + size);
return 0;
}
The problem is not the language. The problem you face is you need to come out with the algorithm first.
Actually this can be easily done by just looking at the first number of the 1D array. In your example it is 6 from (6,3,3,2).
Look for 6 in your 2D array.
Once 6 is found use a loop which loop 4 times (because there are 4 numbers to look for - (6,3,3,2).
In the loop, check whether the subsequent numbers are 3,3,2.
If it is, return the location
Else continue the process to look for 6.
Done!
It will look like this:
for(x=0; x<rows; x++)
for(y=0; y<cols; y++)
{
if(matrix[x][y] == array1D[0])
for(z=1; z<array1DSize; z++){
if(matrix[x][y] != array1D[z])
break;
location = y;
}
}
If you know how to do it with a one dimensional array, you can do it like that in C with multidimensional arrays too!
For instance, say you have a two dimensional array like so:
int array[5][5]; // 5x5 array of ints
You can actually access it in linear fashion, by doing:
(*array)[linear offset]
So that means if you want to access the 2nd column of the 2nd row, you can do:
(*array)[6]
Because the 2nd row starts at index 5, and the second column is at index 1, so you would do (5+1) to get 6. Likewise, the 3rd row would start at index 10, so if you wanted the 2nd column in the third row, you can do (10+1).
Knowing that, you can take your original algorithm and adapt it to access the multidimensional array in a linear fashion. This takes place of the "wrap around" possibility as well.
Trying to make 3 x 3 matrix multiplier but it gives out wrong output. I don't know what I am doing wrong. Two problems that I am facing are:
(1) Some variables store wrong input. For example a[1][1] shows 7 although I entered 1
(2) The matrix multiplication is wrong
#include <stdio.h>
#include <conio.h>
void matrix_format(int m[2][2])
{
int i,j;
printf("\n\n");
for(i=0;i<=2;i++)
{
for(j=0;j<=2;j++)
{
if(j==0)
printf("[ %d |",m[i][j]);
else if(j==1)
printf(" %d |",m[i][j]);
else if(j==2)
printf(" %d ] \n",m[i][j]);
}
}
}
int main(void)
{
void matrix_format(int [2][2]);
int a[2][2], b[2][2], r[2][2],m,i,j;
clrscr();
for(m=1;m<=2;m++)
{
if(m==1)
{
printf("Enter values for the matrix A \n");
}
else
{
printf("\n\nEnter values for the matrix B \n");
}
for(i=0;i<=2;i++)
{
for(j=0;j<=2;j++)
{
if(m==1)
{
printf("A[%d][%d] : ",i+1,j+1);
scanf("%d",&a[i][j]);
}
else if(m==2)
{
printf("B[%d][%d] : ",i+1,j+1);
scanf("%d",&b[i][j]);
}
}
}
}
printf("\n Matrix A : \n");
matrix_format(a);
printf("\n Matrix B : \n");
matrix_format(b);
for(i=0;i<=2;i++)
{
for(j=0;j<=2;j++)
{
r[i][j]= a[i][j] * b[j][i];
}
}
printf("\n Matrix Multiplication Result : \n");
matrix_format(r);
getch();
return 0;
}
output:
Please guide me.
The first problem that jumps out is that all your arrays are 2x2, while they should be 3x3:
m[2][2]
should read
m[3][3]
and so on. The number in brackets is the size of the array, not the index of the last element.
This will explain some of the weirdness, in particular why some elements get mysteriously overwritten.
As to the actual matrix multiplication, your algorithm isn't quite right (assuming what you're trying to implement is the standard linear algebra matrix product). Think about what steps are involved in multiplying two matrices, and what your code is actually doing. Since this is homework, I'll only give you a hint:
Matrix product involves summations of element products.
There are two major problems:
First, a 3*3 matrix is represented by int matrix[3][3] not int matrix[2][2]. The reason you see strange results is that you are writing over array boundaries, effectively writing over the other matrix because their memory locations are adjacent.
Note: An array such as int a[10] can only be indexed from 0 to 9.
Another problem is your multiplication. From math, we know that if we have:
C = A x B
Then we have:
C[i][j] = sum(A[i][k]*A[k][j]) over k
That is in your case:
C[i][j] = A[i][0]*A[0][j]+A[i][1]*A[1][j]+A[i][2]*A[2][j]
So you have to have:
for over i
for over j
C[i][j] = 0
for over k
C[i][j] += A[i][k]*B[k][j]
I have written a simple matrix multiplication program without using pointers. Hopefully this would work for you. I can see that you know how to use functions, so try using them more often. Also your multiplication logic was wrong. Read up on that and then see the code. (If you want to do the matrix multiplication for let's say a 5 x 5 matrix, then you should just change #define SIZE 3 to #define SIZE 5).
#include <stdio.h>
#include <stdlib.h>
#define SIZE 3
void CreateMatrix(char name, int m[SIZE][SIZE]) {
int row, col;
printf("Enter values for the matrix %c:\n", name);
for(row = 0; row < SIZE; row++) {
for(col = 0; col < SIZE; col++) {
printf("%c[%d][%d] : ", name, row + 1, col + 1);
scanf("%d", &m[row][col]);
}
}
printf("\n");
}
void PrintMatrix(char name, int m[SIZE][SIZE]) {
int row, col;
printf("Matrix %c:\n", name);
for (row = 0; row < SIZE; row++) {
printf("[ ");
for (col = 0; col < SIZE; col++) {
printf("%d ", m[row][col]);
}
printf("]\n");
}
printf("\n");
}
void MatrixMultiply(int a[SIZE][SIZE], int b[SIZE][SIZE], int mul[SIZE][SIZE]) {
int row, col, k;
for (row = 0; row < SIZE; row++) {
for (col = 0; col < SIZE; col++) {
mul[row][col] = 0;
for (k = 0; k < SIZE; k++) {
mul[row][col] += a[row][k] * b[k][col];
}
}
}
}
int main() {
int a[SIZE][SIZE];
int b[SIZE][SIZE];
int mul[SIZE][SIZE];
// Create Matrices
CreateMatrix('A', a);
CreateMatrix('B', b);
// Matrix Multiplication
MatrixMultiply(a, b, mul);
// Print Matrices
PrintMatrix('A', a);
PrintMatrix('B', b);
PrintMatrix('M', mul);
}
The output:
Enter values for the matrix A:
A[1][1] : 1
A[1][2] : 2
A[1][3] : 3
A[2][1] : 4
A[2][2] : 5
A[2][3] : 6
A[3][1] : 7
A[3][2] : 8
A[3][3] : 9
Enter values for the matrix B:
B[1][1] : 1
B[1][2] : 2
B[1][3] : 3
B[2][1] : 4
B[2][2] : 5
B[2][3] : 6
B[3][1] : 7
B[3][2] : 8
B[3][3] : 9
Matrix A:
[ 1 2 3 ]
[ 4 5 6 ]
[ 7 8 9 ]
Matrix B:
[ 1 2 3 ]
[ 4 5 6 ]
[ 7 8 9 ]
Matrix M:
[ 30 36 42 ]
[ 66 81 96 ]
[ 102 126 150 ]
First, see #aix' answer regarding the array sizes. Then, the reason the multiplication doesn't work is that you are using the wrong formula. The element at i,j in the result matrix is not simply the product of i,j and j,i from the two matrices being multiplied - instead, every element in row i from the left matrix must be multiplied by the corresponding element from column j from the right matrix, and all the products must be added together. See this illustration in the Wikipedia article.
you have define array of 2*2 i.e. it has index of 0,1.but in your FOR loop you are trying to accept 3 i.e.{0,1,2 }elements in one row. so remove = sign from all FOR loops. or just change the declaration of your Array to [3][3].Also then apply right formula for Matrix multiplication i.e r[0][0]=(a[0][0]*b[0][0])+(a[0][1]*b[1][0])+(a[0][2]*b[2][0]). for first cell so on for other cells,in your case for 3*3 matrix.