另一个矩阵内的矩阵

时间:2018-12-13 00:20:18

标签: c arrays matrix

我应该使用哪种方法编写一个函数来检查另一个矩阵中是否包含一个矩阵? 例如:

     matrix A           matrix B
  1   2.  3.  4   5      2  3
  6   7.   8.  9   10    7  8
  11  12. 13. 14  15     12 13
  16  17  18  19  20

我加了点以指出矩阵A内的矩阵B。

到目前为止,我已经写过:

#include <stdio.h>

int matrica_sadrzana(int* m1, int v1, int s1, int* m2, int v2, int s2){

    /* What needs to go here? */
    return 0;
}

int main() {
    int i,j,v1,v2,s1,s2,sadrzana;
    int matricaA[100][100],matricaB[100][100];
    printf("Unesite visinu i sirinu matrice A: ");
    scanf("%d %d",&v1,&s1);
    printf("Unesite visinu i sirinu matrice B: ");
    scanf("%d %d",&v2,&s2);
    for(i=0; i<v1; i++){
        for(j=0; j<s1; j++){
            scanf("%d",&matricaA[i][j]);

        }
    }
    for(i=0; i<v2; i++){
        for(j=0; j<s2; j++){
            scanf("%d",&matricaB[i][j]);

        }
    }
    sadrzana=matrica_sadrzana(matricaA,v1,s1,matricaB,v2,s2);

    return 0;
}

2 个答案:

答案 0 :(得分:0)

您可以创建一个findNum()函数,该函数返回布尔值true或false,并接受一个行大小,col大小,2d数组(传入col大小指定的第二维)和一个数字您想检查一下。因此,在您的情况下,您可以遍历矩阵A,对矩阵A中的每个元素调用findNum()来检查并查看矩阵B是否包含它。 findNum()会在第一次遇到要检查的数字时返回true。如果号码不存在,那么它将返回false。

例如:

_Bool findNum(int row, int col, int arr2d[][col], int chk) {
    for(int i = 0; i < row; ++i) {
        for(int j = 0; j < col; ++j) {
            if(arr2d[i][j] == chk)
                return 1;
        }
    }

    return 0;
}

使用它(这应该打印三遍“ Match!”,因为其中包含0 arr2d2,但不是5):

int arr2d1[2][2] = {0};
int arr2d2[2][3] = {0};

/* Change a value in arr2d1 so they're not identical */
arr2d1[0][0] = 5;

/* Element we're sending to findNum() */
int element = 0;

/* Traverse through arr2d1 */
for(int i = 0; i < 2; ++i) {
    for(int j = 0; j < 2; ++j) {
        element = arr2d1[i][j];
        /* Check if the current element is contained
         * in arr2d2; do whatever if so */
        if(findNum(2, 3, arr2d2, element)) {
            printf("Match!\n");
        }
    }
}

答案 1 :(得分:0)

您可以使用固定长度数组或可变长度数组来做到这一点。

固定长度数组

您从固定长度数组开始,因此第一个程序跟随您的脚步。传递数组时,必须指定数组的第二维-否则,代码将访问错误的数据。您的编译器应该一直在抱怨对函数的调用。我使用初始化数据,而不是从标准输入中读取数据。输入的代码已被注释掉(并且未经测试)。

#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列中查找与m2的行,其有效行的大小为r2c2有效列(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()函数的额外参数来指定数组的实际大小(r1c1)以及数组中的搜索位置( r0c0)。

#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代码没有。将转储代码添加到第一个程序是很容易的,但是print函数并不通用。可以安排转储RxC矩阵的NxM子段;这在代码编写上有点儿麻烦,但是非常通用,可以在两个程序中使用-但是VLA程序只需将N和R设置为相等,将M和C设置为相等。