简体   繁体   中英

Finding submatrix in one dimensional array - C

Good day, I need a help. We get a homework to write a programme in C which should generate and print bigger and smaller matrix made from "X" and ".". And after that find if the smaller 3x3 matrix is in the bigger one. I tried to make it by one dimensional field, but my programme finds matrix only sometimes. I am not able to find it out where is my mistake and how to fix it. I read some threads on forum, but none of it was helpfull to me. Thanks for any help.

PS Forgive me language mistakes, I am not a native english speaker.

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

/* Generates matrix of given dimensions */
void initMatrix(char *Matrix, int rows, int cols)
{
    for(int i = 0; i < rows; i++)
    {
        for(int j = 0; j < cols; j++)
        {
        Matrix[i*cols+j]= "X.." [rand () % 3];         // 2/3 that X will be generated
        }
    }
}

/* Prints given matrix */
void printMatrix(char *Matrix, int rows, int cols)
{
    for(int i = 0; i < rows; i++)
    {
        for(int j = 0; j < cols; j++)
            {
            printf("%c", Matrix[i * cols + j]);
            }
        printf("\n");
    }
}

int main(void)
{
    int rowM1, colM1;                               // Dimensions of primary (bigger) matrix
    int rowM2 = 3, colM2 = 3;                       // Dimensions of secondary (smaller) matrix
    int first, second;                                      // Position of the begginng of matrix 2 in matrix 1
    int rel_pos;
    int i, j, k, l;
    char *M1 = NULL;                                // Pointer to matrix 1
    char *M2 = NULL;                                // Pointer to matrix 2

    printf("Enter the matrix dimensions separated by a space ([rows] [columns]) : ");
    if (scanf("%d %d", &rowM1, &colM1) != 2)        // Bad parameters
    {
        printf("Wrong parameters.");
        return 1;                                   // End program
    }

    if (rowM1 < rowM2 || colM1 < colM2)
    {
        printf("Matrix 2 can not be found because is bigger than Matrix 1.");
        return 1;
    }

    srand(time(NULL));                              // Randomly generates numbers

    M1 = malloc(rowM1 * colM1 * sizeof(char));      // M1 points to matrix 1
    M2 = malloc(rowM2 * colM2 * sizeof(char));      // M2 points to matrix 2

    initMatrix(M1, rowM1, colM1);                   // Initializes matrix 1
    initMatrix(M2, rowM2, colM2);                   // Initializes matrix 2

    printf("\nMatrix 1:\n");
    printMatrix(M1, rowM1, colM1);                  // Prints matrix 1
    printf("\nMatrix 2:\n");
    printMatrix(M2, rowM2, colM2);                  // Prints matrix 2

    putchar('\n');

    for (i = 0; i < rowM1; i++)
    {
        for(j = 0; j < colM1; j++){
        {
                for (k = 0; k <  rowM2 * colM2; k++)    // checking the smaller matrix
            {
                if(M1[i*rowM1+j] == M2[k])
                {
                    first = i*rowM1;
                    rel_pos = i+1;
                }
                if(j % colM2 == 0)                 // Matrix 2 has ended on this line, move on next one.
                    rel_pos += colM1 - colM2;

                if(M1[rel_pos] == M2[j])           // If character are same, keep searching
                    rel_pos++;

                else                                // else this is not the matrix I'm searching for
                    break;

            }
                if(k == rowM2*colM2)                // if all k cykle went to the end I found the matrix
                    {
                    printf("Matrix found at [%d][%d]", first, second);
                    return 0;
                    }
            }

        }
                if(i*colM1 > i*colM1-colM2)           // matrix cannot be found
                printf("Matrix not found");
                break;
        }

    free(M1);                                       // frees memory of matrix 1
    free(M2);                                       // frees memory of matrix 2
    return 0;
}

Your inner loop for (k = 0; k < rowM2 * colM2; k++) iterates over the contents of the small matrix, and should compare each entry of the small matrix to the corresponding entry in the large matrix (as defined by the start point given by i and j).

The comparison if(M1[i*rowM1+j] == M2[k]) , however, compares all entries of the small matrix with the same entry in the large matrix (the array index of M1 is independent of k).

To fix this, you need to make a fourdimensional loop

for(y0 = 0; y0 < colM1 - colM2 + 1; y0++) {
    for(x0 = 0; x0 < rowM1 - rowM2 + 1; x0++) {
        for(dy = 0; dy < colM2; dy++) {
            for(dx = 0; dx < rowM2; dx++) {
                if(M1[(y0 + dy)*rowM1 + (x0 + dx)] == M2[dy*rowM2 + dx]) {
                    ...
                }
            }
        }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM