I need to solve the following problem for a 5×5 matrix, but to explain I will use an example with a 3×3 matrix:
A = { { 1, 3, 2 }
,{ 3, 2, 3 }
,{ 0, 4, 5 } };
I need to find all distinct sets of 3 (because the matrix is 3x3) positions sharing no row or column with the others, compute the sum of elements of A for each set of positions, and print the minimum of these sums.
Position = (0,0),(1,1),(2,2) sum = 1+2+5 = 8
(0,0),(1,2),(2,1) sum = 1+3+4 = 8
(0,1),(1,0),(2,2) sum = 3+3+5 = 11
(0,1),(1,2),(2,0) sum = 3+3+0 = 6
(2,0),(1,1),(0,2) sum = 0+2+2 = 4
.
.
.
(I think you understood the main principle).
So the output must include: (2,0),(1,1),(0,2) minimal sum = 4
Remember: I actually need to do it for a 5×5 matrix.
A functional, albeit naive, way to do this is to use 6 for-loops (5 nested). Loop from 0 to 2 with the top loop storing its iteration # in an int (called firstRow for example). Similarly the second loop will store firstCol. The third loop will be used to store secondRow so you'll need to continue if secondRow == firstRow. For the last two loops you'll need to check against the indeces for the other two. In the innermost nested loop, call your findSum function with the 3 coordinate pairs.
testCoords(*arr1, *arr2, *arr3)
{
#get the sum
}
#algorithm defined for n = 3
mySearch(n)
{
int coord1[2], coord2[2], coord3[2]; #assume 3by3
int minSum = n * MAX_VAL, obsSum;
for (int r1 = 0; r1 < n; r1++)
{
coord1[0] = r1;
for (int c1 = 0; c1 < n; c1++)
{
coord1[1] = c1;
for (int r2 = 0; r2 < n; r2++)
{
if (r1 != r2)
{
coord2[0] = r2;
for (int c2 = 0; c2 < n; c2++)
{
if (c1 != c2)
{
coord2[1] = c2;
for (int r3 = 0; r3 < n; r3++)
{
if (r1 != r3 && r2 != r3)
{
coord3[0] = r3;
for (int c3 = 0; c3 < n; c3++)
{
coord3[1] = c3;
obsSum = testCoords(coord1, coord2, coord3);
if (obsSum < minSum)
{
minSum = obsSum;
}
}
}
}
}
}
}
}
}
}
}
This will be fine for small arrays such as n=3 or n=5, but the number of iterations quickly gets ridiculous as its n^(n*2). For example, even with 5x5 matrix you'll do 10 million iterations (not too mention a long winded algorithm). A more dynamic algorithm or perhaps a tree implementation is probably a good fit here. For example, a recursive approach could find one index pair (which eliminates a row and column), then calls itself with the resultant (n-1)*(n-1) 2d array -- as so:
int minSum = n * MAX_VAL;
coordSearch(int **matrix, n)
{
int thisCoord[2];
if (n == 1)
{
return matrix[0][0];
}
else
{
for (int i = 0; i < n; i++)
{
thisCoord[0] = i;
for (int j = 0; j < n; j++)
{
thisCoord[1] = j;
##need to update the matrix s.t. row represented by i is removed and col represented by j is removed
##ill leave that up to you -- assume its called updatedMatrix
updatedMatrix = reduce(matrix, i, j);
return matrix[thisCoord[0], thisCoord[1]] + coordSearch(updatedMatrix, n-1);
}
}
}
}
int main(void)
{
#have some 2d structure that is n * n
int minSum = n * MAX_VAL, obsSum;
int row, col;
for (int i = 0; i < n; i++)
{
row = i
for (int j = 0; j < n; j++)
{
col = j;
updatedMatrix = reduce(matrix, row, col);
obsSum = coordSearch(updatedMatrix, n- 1);
if (obsSum < minSum)
{
minSum = obsSum;
}
}
}
}
For a 3x3 2d array, the recursive approach will look at the 9 coordinate pairs at the top level, then in the next level we will be dealing with a 2x2 2d array so we will only consider 4 coordinate pairs, then in the bottom level we just return whichever value resides in our 1x1 "2d array". Complexity is n^2 * (n-1)^2 * .. * 1. Keep in mind though, that each "step" requires updating the matrix which is a operation dense procedure.
Here's another suggestion: all of the sets of locations in the matrix that you want to use can be represented as permutations of an identity matrix whose "1" entries tell you which matrix elements to add up. You then take the minimum over the set of sums for all of the permutations. You can represent a permutation with a simple array since there are only N elements equal to 1 in a permutation of the NxN identity matrix. So call that array p where p(i) tells you which column on the i'th row to use.
So the fundamental observation here is that you want all permutations of the NxN identity matrix, and you can represent these as permutations of (0,1,...,N-1).
Pseudocode might look like:
Given: an NxN matrix (2-D array), M, for which you want the minimal sum of N
elements with no subset falling on the same row or column
minsum = N * max entry in M (just initialized to guarantee >= min sum sought)
foreach permutation p of (0,1,...,N-1):
sum = 0
for i = 0:N-1:
sum += M(i,p(i))
if sum >= minsum: break; # (if we already know this isn't a new min, move on)
if sum < minsum: minsum = sum
print("minimum sum = ", minsum)
Adding a bit of code to remember a particular set of locations that add up to the minimum is left here as an exercise for the reader. Note that this gives up on any permutation as soon as it's not going to be a new minimum sum.
For an NxN array, there are N! permutations, so in practice this gets expensive fast for large N (not your current problem at N = 5). At that point, deeper dynamic programming techniques to quit early on partial results or avoid recomputing subset sums by using, say, memoization would be applicable and desirable.
Most other algorithms are going to do the same basic work in some way that may or may not look obviously similar in code. I like this approach because it has a nice mapping onto a fairly straight-forward understanding in mathematical terms and you can readily identify that what makes it get expensive quickly as N grows is the need to calculate a minimum over a rapidly-expanding set of permutations.
Algorithms to compute all permutations of an array are pretty easy to come by and you get one for free in C++ in the function next_permutation, which is part of the STL. My recommendation is to google "list all permutations" and if you need to work in a particular programming language, add that to the query as well. The algorithm isn't terribly complicated and exists in both recursive and iterative forms. And hey, for the 5x5 case you could probably statically list all 120 permutations anyway.
For some reason, the first output my program is giving, is garbage value, while the second output is correct.
This is a problem from HackerRank.
I know this question has already been asked by someone else. I just want to know what the problem is in my code.
#include <stdio.h>
int main()
{
int index,query;
int count1 = 0;
scanf("%d%d",&index,&query);
for(int i=0;i<index;i++)
{
int b;
scanf("%d",&b);
int A[index][b];
for(int j=0;j<b;j++)
{
scanf("%d",&A[i][j]);
}
count1++;
if(count1<index)
{
continue;
}
int count2=0;
while(count2<query)
{
int d,e;
scanf("%d%d",&d,&e);
printf("%d\n",A[d][e]);
count2++;
}
}
return 0;
}
If the input is:
2 2
3 1 5 4
5 1 2 8 9 3
0 1
1 3
Then the output should be:
5
9
But instead, my output is:
garbage
9
Disclaimer
I didn't even click the link, so I do not know if the solution is correct, but assuming that you got the logic right..
The problem
is that you populate in stages a local to the body of the for loop 2D array, which at the end of your processing, you expect to have it accessible (I mean the complete matrix, populated from every single iteration of the for loop).
Instead, you get only the last's iteration declared array, that's why you get only the A[1][3] element right, and not the A[0][1], since the 2nd row is populated in the last (2nd iteration), while the 1st row is populated in the first iteration (of the firstly declared A), which goes out of scope as soon as the first iteration terminates.
The fix
So, what you need to fix this is to dynamically allocate memory for your matrix, and every time a new dimension for the columns is inputed, resize it with realloc().
I believe that the explanation I have in 2D dynamic array (C) will help you, since what you want is the number of rows fixed, and the number of columns adjustable on every iteration.
Below is an illustration based on the link I shared above, which visualizes what exactly is your matrix (a 1D array of pointers), and shows how the code below manipulates it:
Full code example:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int index,query;
int count1 = 0;
scanf("%d%d",&index,&query);
// An array of `index` (e.g. 2) pointers to integers
int *A[index];
// Initialize all the pointers to NULL
for(int k = 0; k < index; ++k)
A[k] = NULL;
for(int i=0;i<index;i++)
{
int b;
scanf("%d",&b);
// Replaced your 'int A[index][b];' with the following:
// Every time a new number of columns (that's 'b') is read,
// we need to adjust the numbers of columns our matrix ('A') has.
// That means, that for every pointer (row), we need to re-allocate
// the number of columns it points to, which is basically a 1D array, of dimension 'b'
for(int k = 0; k < index; ++k)
A[k] = realloc(A[k], b * sizeof(int) );
for(int j=0;j<b;j++)
{
scanf("%d",&A[i][j]);
}
count1 ++;
if(count1<index)
{
continue;
}
int count2=0;
while(count2<query)
{
int d,e;
scanf("%d%d",&d,&e);
printf("%d\n",A[d][e]);
count2++;
}
}
// Free the dynamically allocated memory
for(int k = 0; k < index; ++k)
free(A[k]);
return 0;
}
Output (for the input provided):
5
9
Pro-tip: The typical methodology of calling realloc() is to use a specific pointer for the reallocation, test that pointer and, if everything worked out ok, change the old pointer, as explained in Does realloc overwrite old contents?, which I didn't do in that post for the sake of being "laconic".
The C VLA is not suitable here. It seems you need to allocate memory dynamically. The only VLA that can be used is an array of pointers to other arrays. All other arrays should be allocated dynamically.
Something like the following.
#include <stdio.h>
#include <stdlib.h>
int main( void )
{
size_t number_of_arrays;
size_t number_of_queries;
scanf( "%zu%zu", &number_of_arrays, &number_of_queries );
int **a = malloc( number_of_arrays * sizeof( int * ) );
for ( size_t i = 0; i < number_of_arrays; i++ )
{
size_t size;
scanf( "%zu", &size );
a[i] = malloc( size * sizeof( int ) );
for ( size_t j = 0; j < size; j++ ) scanf( "%d", &a[i][j] );
}
for ( size_t i = 0; i < number_of_queries; i++ )
{
size_t array_index;
size_t element_index;
scanf( "%zu%zu", &array_index, &element_index );
printf( "%d\n", a[array_index][element_index] );
}
for ( size_t i = 0; i < number_of_arrays; i++ ) free( a[i] );
free( a );
}
If to input
2 2
3 1 5 4
5 1 2 8 9 3
0 1
1 3
then the program output will be
5
9
As for your code then it is invalid. For example the variable b is not initialized so the declaration of the array has undefined behavior.
int b;
scanf("%d",&b);
int A[index][b];
^^^
Hint : Variable sized arrays need to be dynamically allocated, here's how to it in C
int rows;
scanf("%d",&rows);
//2D array
int**A = malloc(sizeof(int*)*rows); //allocate number of rows
//for each row allocate number of colums
for(int i = 0; i < rows; i++)
{
int cols;
scanf("%d",&cols);
A[i] = malloc(sizeof(int)*cols);
}
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.
I want to declare a three dimensional array of strings
where each row has two strings.
Here I am able to declare it:
char *szArray[][2] = {
{"string1", "string2"},
{"string3", "string4"},
{"string5", "string6"},
{0, 0}
};
I want to do the same thing but number of rows are dynamically allocated.
Here you can assume 1st dimension is dynamically decided.
2nd dimension is 2,
3rd dimension is 25.
Tried in many ways no luck :(.
Thanks in advance !
First what you have in your question is not a 3-dimensional array of char but a 2-dimensional array of pointers to char. In C, pointers and arrays are not the same thing.
To answer your question, the simplest way in modern C, C99, is to use variable length arrays, VLA, for your purpose. For a 3-dimensional array you'd do
char szData[x][y][z];
where x, y and z are variables or expressions that are only determined at run time when you hit that declaration.
The inconvenience of VLA are that you have to be careful that they don't become too large for your stack, and that you have to initialize them by assignment to the individual entries (here by a nested for-loop).
To stay with your example of 2-d array of strings
char* szData[x][y];
and then you'd have to assign either individual strings to each of the pointers or to set them to 0.
for (size_t i = 0; i < x; ++i)
for (size_t j = 0; j < y; ++j)
szData[i][j] = 0;
int n = 0 ;
printf("Enter the number of rows\n");
scanf("%d",&n);
char *** szData = (char *** )malloc(n * sizeof(char ** )) ;
//Allocate memroy for each row
for(int i = 0 ; i < n ; i++ )
{
szData[i] = (char ** ) malloc(2 * sizeof(char * )) ;
for ( int j = 0 ; j < 2 ; j++ )
{
szData[i][j] = (char *) malloc (25 * sizeof(char));
}
}
//Assign some data
for( int i = 0 ; i < n ; i++ )
{
sprintf(szData[i][0],"string%d", i);
sprintf(szData[i][1],"string1%d", i);
}
//print all the elements
for( int i = 0 ; i < n ; i++ )
{
printf("%s\n",szData[i][0]);
printf("%s\n",szData[i][1]);
}
//free memory here
for(int i = 0 ; i < n ; i++ )
{
for ( int j = 0 ; j < 2 ; j++ )
{
delete szData[i][j];
}
}
for(int i = 0 ; i < n ; i++ )
{
delete szData[i];
}
delete szData;
I didnt get any error:
#include <stdio.h>
int main(){
char *szArray[][2] = { {"string1", "string2"}, {"string3", "string4"}, {"string5", "string6"}, {0, 0} };
printf("%s\n", szArray[0][0]);
printf("%s\n", szArray[2][0]);
}
Here is the output:
$ gcc test.c
$ ./a.exe
string1
string5
But you cannot print szArray[3][0][0] because it is 0, if you want to initialize the value to whatever, you can set to "\0" instead of just 0
Ok, no compiler here to double check, but you can do this a number of ways. The most straight forward would be to declare a Vector of char[25][3] and let c++ do it for you. Something like Vector foo and then just push_back your dynamic elements. Without a compiler though, I'm not 100% certain that this would work as there are funky rules when it comes to multi-dimensional arrays. You can always undimensionalize your array as a first pass just to get it working as well - something like a Vector and start adding how ever you want. You can also do the vector of vector of char approach and have jagged arrays of chars where and of the 3 dimensions can be dynamic, and this would probably even be more memory efficent. Lots of choices here.