对角遍历2维矩阵

时间:2019-07-16 11:20:42

标签: c loops diagonal

我无法以另一种方式遍历NxM矩阵。

这可能不是我可以尝试的所有东西,但是我已经尝试过在Google上找到它,并使用各种不同的边界值,还尝试一遍又一遍地减去另一个索引,但是我似乎无法抓住它。我做的最后一件事是创建矩阵的副本,并通过for循环交换行,直到最后一个在前,最后一个在后。这可行,但不是我想要的。

从此处开始的循环从矩阵的左上角开始,并从左下角一直到右上角。我希望其他人从左下角开始,然后从右下角到左上角,或者从左上角到右下角进行工作。

循环:

for(int i = 0; i + 1 < ROWCOUNT + COLCOUNT; i++) {
    printf("\n");
    for(int j = 0; j - 1 < i; j++) {
        int n = i - j;
        int m = j;
        if(n < ROWCOUNT && m < COLCOUNT) {
            printf("  %d %d  ", n, m);
        }
    }
}
Output:
  0 0
  1 0    0 1
  2 0    1 1    0 2
  3 0    2 1    1 2    0 3
  4 0    3 1    2 2    1 3    0 4
  5 0    4 1    3 2    2 3    1 4    0 5
  5 1    4 2    3 3    2 4    1 5
  5 2    4 3    3 4    2 5
  5 3    4 4    3 5
  5 4    4 5
  5 5

编辑:我将尝试向您展示我的意图。

A   B   C   D   E   F
G   H   I   J   K   L
M   N   O   P   Q   R
S   T   U   V   W   X
Y   Z   AA  AB  AC  AD
AE  AF  AG  AH  AI  AJ

我的循环通过以下方式遍历6x6矩阵:

A
G  B
M  H  C
S  N  I  D
Y  T  O  J  E
AE Z  U  P  K  F
AF AA V  Q  L
AG AB W  R
AH AC X
AI AD
AJ

我正在寻找一个循环来解决其他问题。基本上是这样的:

AE
AF Y
AG Z  S
AH AA T  M
AI AB U  N  G
AJ AC V  O  H  A
AD W  P  I  B
R  K  D
L  E
F

编辑:@pmg为我提供了解决方案。谢谢!

2 个答案:

答案 0 :(得分:0)

不确定您要寻找的是什么,而是以另一种方式循环:

#include  "stdio.h"
#define ROWCOUNT  6
#define COLCOUNT 6

int main(void) {
    for(int i = ROWCOUNT - 1; i >= 0; i--) {
        for(int j = 0; j < COLCOUNT; j++) {
            printf("  %d %d  ", i, j);
        }
        printf("\n");
    }
}

输出

5 0    5 1    5 2    5 3    5 4    5 5  
4 0    4 1    4 2    4 3    4 4    4 5  
3 0    3 1    3 2    3 3    3 4    3 5  
2 0    2 1    2 2    2 3    2 4    2 5  
1 0    1 1    1 2    1 3    1 4    1 5  
0 0    0 1    0 2    0 3    0 4    0 5  

答案 1 :(得分:0)

两个对角线都具有每个单元格索引加到一个常数或它们的差是常数的属性。在您的情况下,索引必须加一个常量。只需考虑所需对角线上的一个单元格(要打印的第一个单元格),然后将其添加到一个索引时,就将另一个减去相同的数量,使总和相同。这样一来,您可以从零开始加法:

i = 0; j = 0;

然后,将总和加一并遵循:

pru.c:

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

int N = 10;

int main(int argc, char **argv)
{
    int opt;
    while ((opt = getopt(argc, argv, "n:")) != EOF) {
            switch(opt) {
            case 'n': N = atoi(optarg); break;
            }
    } /* while */

    int sum;
    /* maximum value is (N-1) + (N-1) = 2N-2 */
    for (sum = 0; sum <= 2*N - 2; sum++) {
            /* initial values */
            int i = sum < N ? sum : N-1; /* will be decremented */
            int j = sum - i; /* must add to sum, will be incremented */
            char *sep = "";
            for (; i >= 0 && j < N; i--, j++) {
                    printf("%sA[%d, %d]", sep, i, j);
                    sep = " -> ";
            }
            printf("\n");
    }
}

示例代码将打印要打印的索引序列:

$ pru -n 5
A[0, 0]
A[1, 0] -> A[0, 1]
A[2, 0] -> A[1, 1] -> A[0, 2]
A[3, 0] -> A[2, 1] -> A[1, 2] -> A[0, 3]
A[4, 0] -> A[3, 1] -> A[2, 2] -> A[1, 3] -> A[0, 4]
A[4, 1] -> A[3, 2] -> A[2, 3] -> A[1, 4]
A[4, 2] -> A[3, 3] -> A[2, 4]
A[4, 3] -> A[3, 4]
A[4, 4]

对于索引不同的情况,您可以:

pru2.c

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

int N = 10;

int main(int argc, char **argv)
{
    int opt;
    while ((opt = getopt(argc, argv, "n:")) != EOF) {
            switch(opt) {
            case 'n': N = atoi(optarg); break;
            }
    } /* while */

    int dif;
    /* difference ranges from -(N-1) to +(N-1) */
    for (dif = -N+1; dif <= N-1; dif++) {
            /* initial values, dif = i - j */
            int i = dif > 0 ?    0 : dif; /* will be incremented */
            int j = dif > 0 ? -dif :   0; /* will be incremented */
            char *sep = "";
            for (; i < N && j < N; i++, j++) {
                    printf("%sA[%d, %d]", sep, i, j);
                    sep = " -> ";
            }
            printf("\n");
    }
}

将给出:

A[4, 0]
A[3, 0] -> A[4, 1]
A[2, 0] -> A[3, 1] -> A[4, 2]
A[1, 0] -> A[2, 1] -> A[3, 2] -> A[4, 3]
A[0, 0] -> A[1, 1] -> A[2, 2] -> A[3, 3] -> A[4, 4]
A[0, 1] -> A[1, 2] -> A[2, 3] -> A[3, 4]
A[0, 2] -> A[1, 3] -> A[2, 4]
A[0, 3] -> A[1, 4]
A[0, 4]