C语言 对角搜索算法[已关闭]

46qrfjad  于 2023-10-16  发布在  其他
关注(0)|答案(4)|浏览(123)

已关闭,此问题需要更focused。它目前不接受回答。
**想改善这个问题吗?**更新问题,使其只关注editing this post的一个问题。

24天前关闭
Improve this question
我期待实现一个对角线搜索算法,是连续的。这意味着它是一条从MxN网格的顶部开始的长的不间断的线,然后不断迭代直到结束,而不跳到计算每个对角线。
我一直在试图找出这个算法,但我就是看不出来。我会在下面上传我的作品。我尝试用Java或C编写这个算法,然后将其转换为MIPS。我只是找不到真正的算法。

gwbalxhn

gwbalxhn1#

继续@user85421的建议,在Map下面的颜色告诉方向到下一个单元格。

棋盘图案(交替的黄色和绿色)很容易通过测试x+y的奇偶性来决定。在边缘上用红色替换黄色或用蓝色替换绿色很简单,尽管左下角有一个特殊情况。

33qvvth1

33qvvth12#

下面是C中的一个例子,用于迭代计算2D数组的zigzag walk的xy坐标:

#include <stdio.h>

#define M 10
#define N 8

int main(void) {
    int mat[M][N];

    for (int x = 0, y = 0, dx = 1, n = 0; n < M * N; n++) {
        mat[y][x] = n;
        x += dx;
        y -= dx;
        if (x == N) {
            /* exit to the right: go S then SW */
            x -= 1;
            y += 2;
            dx = -1;
        } else
        if (y < 0) {
            /* exit to the top: go E then SW */
            y += 1;
            dx = -1;
        } else
        if (y == M) {
            /* exit to the bottom: go E then NE */
            x += 2;
            y -= 1;
            dx = 1;
        } else
        if (x < 0) {
            /* exit to the left: go S then NE */
            x += 1;
            dx = 1;
        }
    }
    for (int y = 0; y < M; y++) {
        for (int x = 0; x < N; x++) {
            printf(" %3d", mat[y][x]);
        }
        printf("\n");
    }
    return 0;
}

输出量:

0   1   5   6  14  15  27  28
   2   4   7  13  16  26  29  43
   3   8  12  17  25  30  42  44
   9  11  18  24  31  41  45  58
  10  19  23  32  40  46  57  59
  20  22  33  39  47  56  60  69
  21  34  38  48  55  61  68  70
  35  37  49  54  62  67  71  76
  36  50  53  63  66  72  75  77
  51  52  64  65  73  74  78  79

下面是一个没有额外变量的替代方案,使用x + y的奇偶校验:

#include <stdio.h>

#define M 10
#define N 8

int main(void) {
    int mat[M][N];

    for (int x = 0, y = 0, n = 0; n < M * N; n++) {
        mat[y][x] = n;
        if ((x + y) & 1) {
            if (y == M - 1) {
                /* exit to the bottom: go E */
                x += 1;
            } else
            if (x == 0) {
                /* exit to the left: go S */
                y += 1;
            } else {
                /* follow the NE diagonal */
                x -= 1;
                y += 1;
            }
        } else {
            if (x == N - 1) {
                /* exit to the right: go S */
                y += 1;
            } else
            if (y == 0) {
                /* exit to the top: go E */
                x += 1;
            } else {
                /* follow the NE diagonal */
                x += 1;
                y -= 1;
            }
        }
    }
    for (int y = 0; y < M; y++) {
        for (int x = 0; x < N; x++) {
            printf(" %3d", mat[y][x]);
        }
        printf("\n");
    }
    return 0;
}
vzgqcmou

vzgqcmou3#

由于x+y在每条对角线上沿着都是常数,我会这样做:

// x+y is constant along each diagonal
for (int sumxy = 0; sumxy < M+N-1; ++sumxy) {
  // determine the range of y-x
  // 2x = sumxy-diffyx => 0 <= sumxy-diffyx <= 2M-2 => sumxy-2M+2 <= diffyx <= sumxy
  // 2y = sumxy+diffyx => 0 <= sumxy+diffyx <= 2N-2 => -sumxy <= diffyx <= 2N-2-sumxy
  int mindiff = max(sumxy-2*M+2, -sumxy);
  int maxdiff = min(sumxy, 2*N-2-sumxy);
  for (int d=0; d <= maxdiff-mindiff; d+=2) {
    // odd sum => increasing diff, even sum => decreasing
    int diffyx = (sumxy & 1) ? mindiff + d : maxdiff - d;
    int x = (sumxy-diffyx) >> 1;
    int y = (sumxy+diffyx) >> 1;
    // process (x,y)
  }
}
qq24tv8q

qq24tv8q4#

该算法似乎可以描述为:
1.向右移动一步。如果不可能,向下移动一步。如果不可能,请转到后藤6。
1.尽可能地向左下角移动。如果根本不可能,请转到后藤6。
1.向下移动一步。如果不可能,向右移动一步。如果不可能,请转到后藤6。
1.尽可能长地向右移动对角线。如果根本不可能,请转到后藤6。
1.后藤步骤1.
1.完成,即所有要素均已访问

相关问题