您可以使用固定长度数组或可变长度数组来做到这一点。
定长数组
您从固定长度的数组开始,所以第一个程序跟随您的脚步。您必须在传递数组时指定数组的第二维——否则,代码将访问错误的数据。您的编译器应该一直在抱怨对您的函数的调用。我使用初始化数据而不是从标准输入中读取。输入代码被注释掉(并且未经测试)。
#include <stdio.h>
static int matrica_subset(int m1[][100], int r1, int c1, int m2[][100], int r2, int c2)
{
for (int m = 0; m < r2; m++)
{
for (int n = 0; n < c2; n++)
{
printf("ss: m1[%d][%d] = %d; m2[%d][%d] = %d\n", r1+m, c1+n, m1[r1+m][c1+n], m, n, m2[m][n]);
if (m1[r1+m][c1+n] != m2[m][n])
return 0;
}
}
return 1;
}
static int matrica_sadrzana(int m1[][100], int r1, int c1, int m2[][100], int r2, int c2)
{
if (c1 < c2 || r1 < r2)
return 0;
int c_max = c1 - c2 + 1;
int r_max = r1 - r2 + 1;
for (int r = 0; r < r_max; r++)
{
for (int c = 0; c < c_max; c++)
{
printf("sa: m1[%d][%d] = %d; m2[0][0] = %d\n", r, c, m1[r][c], m2[0][0]);
if (m1[r][c] == m2[0][0])
{
if (matrica_subset(m1, r, c, m2, r2, c2) != 0)
{
printf("match at m1[%d][%d]\n", r, c);
return 1;
}
}
}
}
return 0;
}
int main(void)
{
int sadrzana, c1 = 5, c2 = 2, r1 = 4, r2 = 3;
int matricaA[100][100] =
{
{ 1, 2, 3, 4, 5, },
{ 6, 7, 8, 9, 10, },
{ 11, 12, 13, 14, 15, },
{ 16, 17, 18, 19, 20, },
};
int matricaB[100][100] =
{
{ 2, 3, },
{ 7, 8, },
{ 12, 13, },
};
//printf("rows and columns for matrix A: ");
//scanf("%d %d", &r1, &c1);
//printf("rows and columns for matrix B: ");
//scanf("%d %d", &r2, &c2);
//printf("data for matrix A:\n");
//for (int i = 0; i < r1; i++)
//{
// for (int j = 0; j < c1; j++)
// {
// scanf("%d", &matricaA[i][j]);
// }
//}
//printf("data for matrix B:\n");
//for (int i = 0; i < r2; i++)
//{
// for (int j = 0; j < c2; j++)
// {
// scanf("%d", &matricaB[i][j]);
// }
//}
sadrzana = matrica_sadrzana(matricaA, r1, c1, matricaB, r2, c2);
printf("sadrzana: %d\n", sadrzana);
return 0;
}
matrica_subset() 函数从 m1 行开始查找 r1 列 c1 以匹配大小为 r2 活动行和 c2 活动列的 m2 main() 中定义的 100x100 矩阵。
matrica_sadrzana() 协调搜索,检查m2 的左上角是否与m1 中的当前位置匹配,并在匹配时使用matrica_subset() 函数继续搜索。
样本输出:
sa: m1[0][0] = 1; m2[0][0] = 2
sa: m1[0][1] = 2; m2[0][0] = 2
ss: m1[0][1] = 2; m2[0][0] = 2
ss: m1[0][2] = 3; m2[0][1] = 3
ss: m1[1][1] = 7; m2[1][0] = 7
ss: m1[1][2] = 8; m2[1][1] = 8
ss: m1[2][1] = 12; m2[2][0] = 12
ss: m1[2][2] = 19; m2[2][1] = 13
sa: m1[0][2] = 3; m2[0][0] = 2
sa: m1[0][3] = 4; m2[0][0] = 2
sa: m1[1][0] = 6; m2[0][0] = 2
sa: m1[1][1] = 7; m2[0][0] = 2
sa: m1[1][2] = 8; m2[0][0] = 2
sa: m1[1][3] = 9; m2[0][0] = 2
sadrzana: 0
变长数组
使用可变长度数组的替代方法需要matrica_subset() 函数的额外参数来指定数组的实际大小(r1 和c1)以及数组中的搜索位置(r0 和@987654339 @)。
#include <stdio.h>
static void dump_matrix(const char *tag, int r, int c, int m[r][c])
{
printf("%s (%dx%d):\n", tag, r, c);
for (int i = 0; i < r; i++)
{
for (int j = 0; j < c; j++)
printf(" %3d", m[i][j]);
putchar('\n');
}
}
static int matrica_subset(int r1, int c1, int m1[r1][c1], int r0, int c0, int r2, int c2, int m2[r2][c2])
{
for (int m = 0; m < r2; m++)
{
for (int n = 0; n < c2; n++)
{
printf("ss: m1[%d][%d] = %d; m2[%d][%d] = %d\n", r0+m, c0+n, m1[r0+m][c0+n], m, n, m2[m][n]);
if (m1[r0+m][c0+n] != m2[m][n])
return 0;
}
}
return 1;
}
static int matrica_sadrzana(int r1, int c1, int m1[r1][c1], int r2, int c2, int m2[r2][c2])
{
if (c1 < c2 || r1 < r2)
return 0;
int c_max = c1 - c2 + 1;
int r_max = r1 - r2 + 1;
for (int r = 0; r < r_max; r++)
{
for (int c = 0; c < c_max; c++)
{
printf("sa: m1[%d][%d] = %d; m2[0][0] = %d\n", r, c, m1[r][c], m2[0][0]);
if (m1[r][c] == m2[0][0])
{
if (matrica_subset(r1, c1, m1, r, c, r2, c2, m2) != 0)
{
printf("match at m1[%d][%d]\n", r, c);
return 1;
}
}
}
}
return 0;
}
int main(void)
{
int sadrzana, c1 = 5, c2 = 2, r1 = 4, r2 = 3;
int matricaA[4][5] =
{
{ 1, 2, 3, 4, 5, },
{ 6, 7, 8, 9, 10, },
{ 11, 12, 13, 14, 15, },
{ 16, 17, 18, 19, 20, },
};
int matricaB[3][2] =
{
{ 2, 3, },
{ 7, 8, },
{ 12, 13, },
};
//printf("rows and columns for matrix A: ");
//scanf("%d %d", &r1, &c1);
//printf("rows and columns for matrix B: ");
//scanf("%d %d", &r2, &c2);
//printf("data for matrix A:\n");
//for (int i = 0; i < r1; i++)
//{
// for (int j = 0; j < c1; j++)
// {
// scanf("%d", &matricaA[i][j]);
// }
//}
//printf("data for matrix B:\n");
//for (int i = 0; i < r2; i++)
//{
// for (int j = 0; j < c2; j++)
// {
// scanf("%d", &matricaB[i][j]);
// }
//}
dump_matrix("Matrix A", r1, c1, matricaA);
dump_matrix("Matrix B", r2, c2, matricaB);
sadrzana = matrica_sadrzana(r1, c1, matricaA, r2, c2, matricaB);
printf("sadrzana: %d\n", sadrzana);
return 0;
}
样本输出:
Matrix A (4x5):
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15
16 17 18 19 20
Matrix B (3x2):
2 3
7 8
12 13
sa: m1[0][0] = 1; m2[0][0] = 2
sa: m1[0][1] = 2; m2[0][0] = 2
ss: m1[0][1] = 2; m2[0][0] = 2
ss: m1[0][2] = 3; m2[0][1] = 3
ss: m1[1][1] = 7; m2[1][0] = 7
ss: m1[1][2] = 8; m2[1][1] = 8
ss: m1[2][1] = 12; m2[2][0] = 12
ss: m1[2][2] = 13; m2[2][1] = 13
match at m1[0][1]
sadrzana: 1
惊喜,惊喜——它返回相同的结果。搜索功能适用于可变长度数组;数据仍然存储在固定大小的数组中(因为您不能对 VLA 使用初始化程序),但大小比原始代码中的要小得多。
VLA 代码还会转储输入矩阵; FLA 代码没有。将转储代码添加到第一个程序中是相当容易的,但打印功能并不那么通用。可以安排转储 RxC 矩阵的 NxM 子段;这对代码来说有点繁琐,但非常通用,可以在两个程序中使用——但 VLA 程序会简单地设置 N 和 R 相等,M 和 C 相等。