Reputation: 334
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:
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.
Upvotes: 0
Views: 340
Reputation: 755114
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
Upvotes: 2
Reputation: 68099
size_t
)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
Upvotes: 0