Two-dimensional Arrays (matrices) in C - c
I'm writing code that checks if m2 matrix is a sub-matrix of m1.
Currently I have created a method that receives matrix m1 and matrix m2 of fixed size.
First of all I check that m1 is larger than m2 otherwise m2 cannot be a sub-matrix of m1. Then I have the variable result which indicates 1 if m2 is sub-matrix, or indicates 0 if it is not.
I can't find the right technique to check this thing out. I have started scanning the rows and columns of the arrays, but I don't know how to correctly structure the code to verify it correctly.
This is the code:
void CheckSubMatrix (int rows, int cols, int m1[][cols], int m2[2][2]){
int rowsm2=2;
int colsm2=2;
int result=1;
if(rows >= rowsm2 && cols >= colsm2){
for(int i=0; i<rows; i++){
for(int j=0; j<cols; j++){
if(m1[i][j] != m2[i][j]
result=0;
}
}
} else {
result = 0;
if (result)
printf("Is a Sub-Matrix");
else
printf("Is not a Sub-Matrix");
I'm a beginner and I'm trying to understand how two-dimensional arrays and matrices work in order to understand even the simplest one-dimensional arrays.
Thanks to those who will help me.
Note:
example of sub-matrix: image
EDIT:
I know that the code if(m1[i][j] != m2[i][j] result=0; doesn't work, because the program will take the values of i and j at the last for loop. But I just didn't know how to be able to implement it.
Making judicious use of functions makes the code easier, I think. Using VLA notation for all array arguments means that the code can handle your three test cases, plus a couple of extras with non-square matrices. (The use of void CheckSubMatrix (int rows, int cols, int m1[][cols], int m2[2][2]){ in the code in the question prevents any of the sample tests from working; that checking function only accepts 2x2 sub-matrices). Since the code is only checking the matrices, the matrices should be specified with the const qualifier.
#include <stdio.h>
#include <assert.h>
static int SubMatrixHere(int r, int c,
int rows1, int cols1, const int m1[rows1][cols1],
int rows2, int cols2, const int m2[rows2][cols2])
{
assert(r + rows2 <= rows1 && c + cols2 <= cols1);
for (int i = 0; i < rows2; i++)
{
for (int j = 0; j < cols2; j++)
{
if (m1[r+i][c+j] != m2[i][j])
return 0;
}
}
return 1;
}
static int CheckSubMatrix(int rows1, int cols1, const int m1[rows1][cols1],
int rows2, int cols2, const int m2[rows2][cols2])
{
if (rows1 < rows2 || cols1 < cols2)
return 0;
int ub_rows = rows1 - rows2 + 1;
int ub_cols = cols1 - cols2 + 1;
for (int i = 0; i < ub_rows; i++)
{
for (int j = 0; j < ub_cols; j++)
{
/* The test for m1[i][j] == m2[0][0] is a big saving */
if (m1[i][j] == m2[0][0] &&
SubMatrixHere(i, j, rows1, cols1, m1, rows2, cols2, m2))
return 1;
}
}
return 0;
}
static void dump_matrix(const char *tag, int rows, int cols, const int matrix[rows][cols])
{
printf("%s (%dx%d):\n", tag, rows, cols);
for (int i = 0; i < rows; i++)
{
const char *pad = "";
int length = 0;
for (int j = 0; j < cols; j++)
{
length += printf("%s%d", pad, matrix[i][j]);
if (length > 60)
{
putchar('\n');
length = 0;
pad = "";
}
else
pad = ", ";
}
if (length > 0)
putchar('\n');
}
putchar('\n');
}
static void test_submatrix(const char *t1, int r1, int c1, const int m1[r1][c1],
const char *t2, int r2, int c2, const int m2[r2][c2])
{
dump_matrix(t1, r1, c1, m1);
dump_matrix(t2, r2, c2, m2);
if (CheckSubMatrix(r1, c1, m1, r2, c2, m2))
printf("%s is a sub-matrix of %s\n", t2, t1);
else
printf("%s is not a sub-matrix of %s\n", t2, t1);
putchar('\n');
}
int main(void)
{
int m1[4][4] =
{
{ 1, 4, 6, 8 },
{ 2, 5, 7, 0 },
{ 3, 6, 9, 0 },
{ 4, 5, 8, 1 },
};
int m2[3][3] =
{
{ 1, 4, 6 },
{ 2, 5, 7 },
{ 3, 6, 9 },
};
int m3[3][3] =
{
{ 5, 7, 0 },
{ 6, 9, 0 },
{ 5, 8, 1 },
};
int m4[3][3] =
{
{ 1, 4, 6 },
{ 2, 5, 7 },
{ 3, 6, 2 },
};
test_submatrix("m1", 4, 4, m1, "m2", 3, 3, m2);
test_submatrix("m1", 4, 4, m1, "m3", 3, 3, m3);
test_submatrix("m1", 4, 4, m1, "m4", 3, 3, m4);
const int m5[6][4] =
{
{ 68, 59, 61, 70 },
{ 65, 86, 44, 9 },
{ 23, 55, 24, 31 },
{ 51, 21, 10, 99 },
{ 19, 99, 43, 95 },
{ 64, 25, 79, 67 },
};
const int m6[2][3] =
{
{ 55, 24, 31 },
{ 21, 10, 99 },
};
const int m7[4][2] =
{
{ 44, 9 },
{ 24, 31 },
{ 10, 99 },
{ 43, 96 },
};
test_submatrix("m5", 6, 4, m5, "m6", 2, 3, m6);
test_submatrix("m5", 6, 4, m5, "m7", 4, 2, m7);
return 0;
}
Output:
m1 (4x4):
1, 4, 6, 8
2, 5, 7, 0
3, 6, 9, 0
4, 5, 8, 1
m2 (3x3):
1, 4, 6
2, 5, 7
3, 6, 9
m2 is a sub-matrix of m1
m1 (4x4):
1, 4, 6, 8
2, 5, 7, 0
3, 6, 9, 0
4, 5, 8, 1
m3 (3x3):
5, 7, 0
6, 9, 0
5, 8, 1
m3 is a sub-matrix of m1
m1 (4x4):
1, 4, 6, 8
2, 5, 7, 0
3, 6, 9, 0
4, 5, 8, 1
m4 (3x3):
1, 4, 6
2, 5, 7
3, 6, 2
m4 is not a sub-matrix of m1
m5 (6x4):
68, 59, 61, 70
65, 86, 44, 9
23, 55, 24, 31
51, 21, 10, 99
19, 99, 43, 95
64, 25, 79, 67
m6 (2x3):
55, 24, 31
21, 10, 99
m6 is a sub-matrix of m5
m5 (6x4):
68, 59, 61, 70
65, 86, 44, 9
23, 55, 24, 31
51, 21, 10, 99
19, 99, 43, 95
64, 25, 79, 67
m7 (4x2):
44, 9
24, 31
10, 99
43, 96
m7 is not a sub-matrix of m5
Use the correct types for sizes (size_t)
You need more loops
int issubmatrix(size_t hrows, size_t hcols, int (*haystack)[hcols],
size_t nrows, size_t ncols, int (*needle)[ncols])
{
int itis = 0;
int exitloop = 0;
if(haystack && needle && ncols <= hcols && nrows <= hrows)
{
for(size_t start_row = 0; start_row <= hrows - nrows; start_row++)
{
for(size_t start_col = 0; start_col <= hcols - ncols; start_col++)
{
exitloop = 0;
for(size_t row = 0; row < nrows; row++)
{
for(size_t col = 0; col < ncols; col++)
{
if(haystack[start_row + row][start_col + col] != needle[row][col])
{
exitloop = 1;
break;
}
if(exitloop) break;
}
if(exitloop) break;
}
if(!exitloop) itis = 1;
}
if(itis) break;
}
}
return itis;
}
int main(void)
{
int haystack[][4] = {
{1,4,6,8},
{2,5,7,0},
{3,6,9,0},
{4,5,8,1},
};
int needle1[][3] =
{
{1,4,6},
{2,5,7},
{3,6,9},
};
int needle2[][3] =
{
{5,7,0},
{6,9,0},
{5,8,1},
};
int needle3[][3] =
{
{1,4,6},
{2,5,7},
{3,6,2},
};
printf("%d\n", issubmatrix(4,4, haystack, 3,3, needle1));
printf("%d\n", issubmatrix(4,4, haystack, 3,3, needle2));
printf("%d\n", issubmatrix(4,4, haystack, 3,3, needle3));
}
https://godbolt.org/z/YTMfWP8ca
Related
How to create a cglm Mat4 from a float[16] array?
I know C++ has glm::make_mat4() with #include <glm/gtc/type_ptr.hpp>, but there does not seem to be a make_mat4() function available in CGLM. Can someone please tell me how to create a CGLM Mat4 from a float[16] array? I tried the following, but the Mat4 does not seem to print the float values I'm expecting. #include "cglm/cglm.h" #include "cglm/call.h" void main() { // Atempt #1 float aaa[16] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }; mat4 bbb = { { aaa[0],aaa[1],aaa[2],aaa[3] }, { aaa[4],aaa[5],aaa[6],aaa[7] }, { aaa[8],aaa[9],aaa[10],aaa[11] }, { aaa[12],aaa[13],aaa[14],aaa[15] } }; for (int i = 0; i < 4; i++) { for (int k = 0; k < 4; k++) { printf("%d", bbb[i][k]); printf("\n"); } } printf("\n"); // Atempt #2 //void *memcpy(void *dest, const void * src, size_t n) memcpy(bbb, aaa, sizeof(aaa)); for (int i = 0; i < 4; i++) { for (int k = 0; k < 4; k++) { printf("%d", bbb[i][k]); printf("\n"); } } }
You need to make a void main() function as an entry point. Otherwise the compiler wont know where you program starts. int main(){ float aaa[16] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }; float bbb[4][4] = { { aaa[0],aaa[1],aaa[2],aaa[3] }, { aaa[4],aaa[5],aaa[6],aaa[7] }, { aaa[8],aaa[9],aaa[10],aaa[11] }, { aaa[12],aaa[13],aaa[14],aaa[15] } }; for (int i = 0; i < 4; i++) { for (int k = 0; k < 4; k++) { printf("%f", bbb[i][k]); printf("\n"); } } printf("\n"); } This code works in for me. The diffrence to your code is: The main function I changed the data type from the bbb array to float and used the dimensions 4 by 4 I used %f in the printf function for printing the values
How do I finish this method which finds largest integer in an array passed as a parameter?
I'm stuck with this method which should "find the largest integer in an array passed as a parameter and also output the count of the maximum value", not sure what I'm doing wrong. Thanks public class q3 { public static void main(String[] args) { int[] arraY = {20, 20, 10, 19, 1, 4, 25, 19, 1, 11, 15, 11, 29, 27, 7, 22, 14, 26, 2, 6, 18}; findMax(arraY); } public static void findMax(int[] arraY) { int max_value = arraY[0]; int countMax = 0; for (int i = 1; i < arraY.length; i++) { if (arraY[i] > max_value) { max_value = arraY[i]; } for (i = 0; i < arraY.length; i++) { if (arraY[i] == max_value) { //System.out.println(array[i]); //System.out.println(max_value); countMax++; } } } System.out.println("The maximum value is: " + max_value); System.out.println("The count is: " + countMax); } } edit: was an issue with scope, have rearranged the formatting and it now returns the correct result code updated below public class q3 { public static void main(String[] args) { int[] arraY = {20, 20, 10, 19, 1, 4, 25, 19, 1, 11, 15, 11, 29, 27, 7, 22, 14, 26, 2, 6, 18}; //int[] arraY = {30, 9, 20, 9}; findMax(arraY); } public static void findMax(int[] arraY) { int max_value = arraY[0]; int countMax = 0; for (int i = 1; i < arraY.length; i++) { //System.out.println(arraY[i]); if (arraY[i] > max_value) { max_value = arraY[i]; } } for (int i = 0; i < arraY.length; i++) { if (arraY[i] == max_value) { //System.out.println(arraY[i]); //System.out.println(max_value); countMax++; } } System.out.println("The maximum value is: " + max_value); System.out.println("The count is: " + countMax); } }
How to add adjacent array items in c with pointers?
#include <stdio.h> void add_adjacents() { int num1[5] = {1, 2, 3, 4, 5}; int num2[5] = {10, 20, 30, 40, 50}; int final[5]; for (int i=0; i<sizeof(num1); i++) { final[i] = num1[i] + num2[i]; } for (int c=0; c<sizeof(final)/sizeof(final[0]); c++) { printf("%d\n", final[c]); } } void main() { add_adjacents(); } So, I did the above without the pointers. But with pointers, here is my attempt: I'm still new to pointers, and I'm playing with different practice problems. #include <stdio.h> void add_adjacents() { int num1[5] = {1, 2, 3, 4, 5}; int num2[5] = {10, 20, 30, 40, 50}; int final[5]; for (; *num1 != '\0'; *num1++) { *final = *num1 + *num2; } for (int c=0; c<sizeof(final)/sizeof(final[0]); c++) { printf("%d\n", final[c]); } } void main() { add_adjacents(); }
The following does the trick: void add_adjacents() { int num1[5] = {1, 2, 3, 4, 5}; int num2[5] = {10, 20, 30, 40, 50}; int final[5], c; int *n1= num1, *n2=num2, *f=final; for (; n1<&num1[5]; ) { *f++ = *n1++ + *n2++; } for (c=0; c<sizeof(final)/sizeof(final[0]); c++) { printf("%d\n", final[c]); } }
How can choose the five largest values in an array and put them in a new array?
How can choose the five largest values in an array and put them in a new array? int[] a = { 1, 2, 5, 2, 4, 6, 8, 9, 1, 19 }; int[] largestValues = new int[5]; for (int i=0; i < 5; i++ ) { System.out.println(largestValues[i]); }
You can use following code For Eg. public static void main(String args[]) { int i; int large[] = new int[5]; int array[] = { 33, 55, 13, 46, 87, 42, 10, 34, 43, 56 }; int max = 0, index; for (int j = 0; j < 5; j++) { max = array[0]; index = 0; for (i = 1; i < array.length; i++) { if (max < array[i]) { max = array[i]; index = i; } } large[j] = max; array[index] = Integer.MIN_VALUE; System.out.println("Largest " + j + " : " + large[j]); } }
How to compare arrays in C
I need to print the largest numbers in an array but my program keeps outputting the wrong numbers. What am i doing wrong? int main(void) { int i, x,largest1,largest2, nums[5][4] = { { 5, 6, 8, 9 }, { 3, -55, 6, 89 }, { 1023, 43, -2, 0 }, { 0, 12, 45, 12 }, { -4, 901, 34, 294 } }; for (i = 0; i < 5; i++) { for (x = 0; x < 4; x++) { largest1 = 0; largest2 = 0; if (nums[i] > largest1) largest1 = nums[i]; if (nums[x] > largest2) largest2 = nums[x]; } } printf("\n 1st largest: %d \n 2nd largest: %d \n\n", largest1, largest2); system("pause"); }
Please check the data type of nums[i], its not an int. What you need is compare each value, say nums[i][x] Do not initialize your largest number holder inside the loop. Otherwise, the largest number from previous iteration will be lost. if the array contains all -ve numbers, initializing the highest number holder will 0 is faulty. Check the below code[[ Tested on linux ]] for getting the idea. [For largest number only] #include <stdio.h> #include <stdlib.h> #include <limits.h> int main(void) { int i, x,largest1, nums[5][4] = { { 5, 6, 8, 9 }, { 3, -55, 6, 89 }, { 1023, 43, -2, 0 }, { 0, 12, 45, 12 }, { -4, 901, 34, 294 } }; largest1 = INT_MIN; for (i = 0; i < 5; i++) { for (x = 0; x < 4; x++) { if (nums[i][x] > largest1) largest1 = nums[i][x]; } } printf("Largest number is %d\n", largest1); return 0; } EDIT: The code modification to include the second largest [and so on..] number display, is as per below logic #include <stdio.h> #include <stdlib.h> #include <limits.h> int main(void) { int i, x,largest1,largest2, nums[5][4] = { { 5, 6, 8, 9 }, { 3, -55, 6, 89 }, { 1023, 43, -2, 0 }, { 0, 12, 45, 12 }, { -4, 901, 34, 294 } }; largest1 = INT_MIN; largest2 = INT_MIN; for (i = 0; i < 5; i++) { for (x = 0; x < 4; x++) { if (nums[i][x] > largest2) largest2 = nums[i][x]; if ( largest2 > largest1) { largest2 = largest1; largest1 = nums[i][x]; } } } printf("Largest number is %d, second largest is %d\n", largest1, largest2); return 0; }
First of all, you should initialized largest1 and largest2 variables with the smallest possible integer values. Initializing them with 0 will give wrong result if all the numbers in your array are negative integers. Also you should not re-initialize the largest1 and largest2 everytime you enter the inner loop. I've corrected your code below. Please note that I've not tested the following code myself. int i, x; int largest1 = -32766; int largest2 = -32767; int nums[5][4] = { { 5, 6, 8, 9 }, { 3, -55, 6, 89 }, { 1023, 43, -2, 0 }, { 0, 12, 45, 12 }, { -4, 901, 34, 294 } }; for (i = 0; i < 5; i++) { for (x = 0; x < 4; x++) { if (nums[i][x] > largest1) { largest2 = largest1; largest1 = nums[i][x]; } else if (num[i][x] > largest2) { largest2 = num[i][x]; } } } printf("\n 1st largest: %d \n 2nd largest: %d \n\n", largest1, largest2); system("pause");
Please make the following modifications. You have to access a 2-D array with 2 parameters to get that [x,y] value to compare. int main(void) { int i, x,largest1,largest2, nums[5][4] = { { 5, 6, 8, 9 }, { 3, -55, 6, 89 }, { 1023, 43, -2, 0 }, { 0, 12, 45, 12 }, { -4, 901, 34, 294 } }; for (i = 0; i < 5; i++) { for (x = 0; x < 4; x++) { largest1 = 0; largest2 = 0; if (nums[i][x] > largest1) largest1 = nums[i][x]; if (nums[i][x] > largest2) largest2 = nums[i][x]; } } printf("\n 1st largest: %d \n 2nd largest: %d \n\n", largest1, largest2); system("pause"); } Hope it helps! Please mark the answer right if its helpful and close the question.
You can move all the integer to a one dimensional array... then sort it. Then print the largest two element. Try this code... #include<stdio.h> #include<algorithm> using namespace std; int main(void) { int i, x,largest1,largest2, save[30], j=0, nums[5][4] = { { 5, 6, 8, 9 }, { 3, -55, 6, 89 }, { 1023, 43, -2, 0 }, { 0, 12, 45, 12 }, { -4, 901, 34, 294 } }; for (i = 0; i < 5; i++) { for (x = 0; x < 4; x++) { save[j++]=nums[i][x]; } } sort(save,save+j); printf("\n 1st largest: %d \n 2nd largest: %d \n\n", save[j-1], save[j-2]); system("pause"); }
Try this : int main(void) { int i, x,largest1,largest2, nums[5][4] = { { 5, 6, 8, 9 }, { 3, -55, 6, 89 }, { 1023, 43, -2, 0 }, { 0, 12, 45, 12 }, { -4, 901, 34, 294 } }; largest1 = 0; largest2 = 0; for (i = 0; i < 5; i++) { for (x = 0; x < 4; x++) { if (nums[i][x] > largest1) largest1 = nums[i][x]; if (nums[i][x] > largest2 && nums[i][x] < largest1) largest2 = nums[i][x]; } } printf("\n 1st largest: %d \n 2nd largest: %d \n\n", largest1, largest2); system("pause"); }
everyone has already provided you with syntactically correct program. just a slight addition (I thought may be this is what u wanted according to your prog) : if (nums[i][x] > largest1) { largest2 = largest1; largest1 = nums[i][x]; } if (nums[i][x] > largest2) largest2 = nums[i][x]; then largest1 and largest2 will have ur desired values. and yeah, don't forget to initialize your initial values to lowest limit of int first.
Try this solution. Here we are assigning new max value to largest1 and if we are getting again new max value we will assign old max value to largest2 , which will become the second largest value. int main(void) { int i, x,largest1,largest2, nums[5][4] = { { 5, 6, 8, 9 }, { 3, -55, 6, 89 }, { 1023, 43, -2, 0 }, { 0, 12, 45, 12 }, { -4, 901, 34, 294 } }; largest1 = 0; for (i = 0; i < 5; i++) { for (x = 0; x < 4; x++) { largest1 = 0; largest2 = 0; if (nums[i][x] > largest1){ largest2 = largets1; // assign last max value to `largest2`, it will be second max largest1 = nums[i][x]; // getting new max value } } } printf("\n 1st largest: %d \n 2nd largest: %d \n\n", largest1, largest2); system("pause"); }