【问题标题】:C Find sub-symmetric matrix in one big matrixC 在一个大矩阵中找到亚对称矩阵
【发布时间】:2025-12-24 13:10:12
【问题描述】:

我试图在一个大矩阵中找到所有的子对称矩阵,但我只得到了一些子对称矩阵,其中一些是不正确的。

在我的函数中,我找到了所有的子矩阵,并尝试将所有方形子矩阵发送到检查子矩阵是否对称的函数,如果子矩阵是对称的,我打印矩阵。

主要-

int main() {
    int matrix[][8] = {{1, 2, 0, 3, 2, 1, 0, 9},
                        {2, 3, 4, 1, 2, 3, 4, 5},
                        {3, 4, 6, 2, 5, 6, 7, 86},
                        {9, 5, 8, 3, 6, 8, 9, 8},
                        {6, 7, 1, 4, 7, 9, 1, 9}};
    findSubMatrix(matrix, 5, 8);

    return 0;
}

findSubMatrix -

void findSubMatrix(int matrix[][8], int rows, int cols) {
    for (int i = 0; i <= cols; i++) {
        for (int j = i; j <= cols; j++) {
            for (int m = 0; m <= rows; m++) {
                for (int n = m; n <= rows; n++) {
                    if (n - m == j - i && n - m > 0) {
                        if (isSymmetric(matrix, i, j, m, n) == 1) {
                            for (int k = m; k <= n; k++) {
                                for (int l = i; l <= j; l++) {
                                    printf("%d ", matrix[k][l]);
                                }
                                printf("\n");
                            }
                            printf("\n");
                        }
                    }
                }
            }
        }
    }
}

是对称的-

int isSymmetric(int matrix[][8], int rowStart, int rowEnd, int colStart, int colEnd) {

    for (int i = colStart; i < colEnd; i++) {
        for (int j = rowStart; j < rowEnd; j++) {
            if (matrix[j][i] != matrix[i][j]) {
                return -1;
            }
        }
    }
    return 1;
}

感谢您的帮助。

【问题讨论】:

  • 除了您有一个 5 行 x 8 列的矩阵(但您将 8 和 5 传递给findSubMatrix)这一事实之外,您确定您正确计算了isSymmetric 中的索引吗?
  • @Bob__ 我更新了矩阵边界,但我不确定 isSymmetric 中的索引
  • 嗯。除了 Bob 提到的混淆之外,您还可以交换 findSubMatrixisSymmetric 之间的含义。循环遍历所有可能的子矩阵维度,然后选择那些形成方阵的维度是浪费的。只需遍历方阵的大小并在它不再适合时停止。此外,当您测试矩阵是否对称时,测试a[i][j] == a[j][i] 仅在ij 是子矩阵的索引时才有用;你必须调整这些指数。

标签: c matrix


【解决方案1】:

所有子矩阵,无论是经过测试还是打印,都应该是方形的,所以我会使用与 OP 不同的签名。以这个辅助函数为例,它打印出一个子矩阵,给定一个用 VLA 表示法传递的更大的矩阵、一个起点(左上角的索引)和一个大小:

void print_submatrix(int cols, int m[][cols],
                     int first_row, int first_col, int n)
{
    for (int r = 0; r < n; ++r) {
        for (int c = 0; c < n; ++c) {
            printf("%3d", m[first_row + r][first_col + c]);
        }
        putchar('\n');
    }
    putchar('\n');
}

这应该有助于我们找到正确的公式来评估检查对称性的函数中的索引。

int is_symmetric(int cols, int matrix[][cols],
                 int first_row, int first_col, int n)
{
    for (int i = 0; i < n; ++i) {
        for (int j = i + 1; j < n; ++j) {
        //       ^^^^^^^^^ I'll loop only through half the sub-matrix

            if (    matrix[first_row + i][first_col + j]
                 != matrix[first_row + j][first_col + i] ) {
                //         ^^^^^^^^^^^^^  ^^^^^^^^^^^^^
                //         Note that the starting point (top left corner) is fixed,
                //         while the offset is changing        
                return 0;
            }
        }
    }
    return 1;
}

外部循环也可以重写

void find_sym_submatrices(int rows, int cols, int matrix[][cols])
{
    // For every possible top left corner...
    for (int i = 0, mi = rows; i < rows; ++i, --mi) {
        for (int j = 0, mj = cols; j < cols; j++, --mj) {
            // For every possible square matrix (which fits in size).
            const int m = mj < mi ? mj : mi;
            for (int n = 2; n <= m; ++n) {
                if (is_symmetric(cols, matrix, i, j, n) == 1) {
                    print_submatrix(cols, matrix, i, j, n);
                }
                else {
                    break;  // Yeap, there's no need to check the bigger ones.
                }
            }
        }
    }
}

直播,here

【讨论】: