" Wave算法" (基于Lee的算法)在C中

时间:2017-06-19 14:49:17

标签: c arrays

我是从A点到B点的最短路程编写程序计算。 我有一个带有值的地图(矩阵):

  • 0是块(墙,无法通过);
  • 1是免费的方式(你可以通过);
  • 11是A点(起点);
  • 22是B点(终点)。

我已经阅读了一些文章应该如何运作,并试图实现我自己的版本,但已经堆积。

在下面的代码中,我声明了两个数组:一个带有Map和更改数组的数组" visited"在运行程序演示访问点时。

我检查4个方向(不是对角线)的单元格为1或0.如果它是1(可能通过),我将计数器增加1.对于不计算前一个单元格I'我试图避免这种情况。

结果我想看到"访问"带有几条线的矩阵,显示了到达B点的方式(1,2,3,... 15)。

现在我的地图看起来不正确,甚至没有关闭。

我在算法中遗漏了什么,我应该考虑什么以及如何修复我的程序?

谢谢。

P.S。我写了一些函数来实现一个带有0值的新数组,可以自由计算单元格和打印数组。

main.c中:

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

#define WIDTH 8
#define HEIGHT 8

int mapZero(int map[WIDTH][WIDTH]);
int mapPrint(int map[WIDTH][HEIGHT]);
int mapInit(int map[WIDTH][WIDTH]);
int findFreeToGoCells(int map[WIDTH][WIDTH]);

int main(int argc, char * argv[])
{
    short int prevPosition;
    short int currPosition;
    short int nextPosition;
    short int lastPosition;

    int visited[WIDTH][HEIGHT];

    unsigned int count;
    unsigned int max;

    mapZero(visited);

    int map[WIDTH][HEIGHT] =
    {
        { 11, 1, 1, 1, 1, 0, 0, 1 },
        { 0, 1, 1, 1, 1, 1, 0, 1 },
        { 0, 0, 1, 0, 1, 1, 1, 0 },
        { 1, 0, 1, 1, 1, 0, 1, 1 },
        { 0, 0, 0, 1, 0, 0, 0, 1 },
        { 1, 0, 1, 1, 1, 0, 0, 1 },
        { 0, 0, 0, 0, 1, 0, 0, 1 },
        { 0, 1, 1, 1, 1, 1, 1, 22 },

    };

    printf("Matrix of zeroed-visited cells:\n\n");
    mapPrint(visited);

    printf("Matrix of the map:\n\n");
    mapPrint(map);

    printf("Ways: %d\n", findFreeToGoCells(map));

    prevPosition = map[0][0];
    currPosition = 0;

    count = 0;
    max = WIDTH * HEIGHT;

    for (int i = 0; i < WIDTH; ++i)
    {
        for (int j = 0; j < HEIGHT; ++j)
        {
            if (((i >= 0) && (i < WIDTH)) && ((j >= 0) && (j < HEIGHT)))
            {
                // [i + 1][j] 
                if (map[i + 1][j] == 1)
                {
                    map[i][j] = prevPosition;
                    if (prevPosition)
                        visited[i + 1][j] = count++;

                }
                if (map[i + 1][j] == 0)
                {
                    visited[i + 1][j] = map[i + 1][j];
                }

                // [i - 1][j]
                if (map[i - 1][j] == 1)
                {
                    map[i][j] = prevPosition;
                    if (prevPosition)
                        visited[i - 1][j] = count++;
                }
                if (map[i - 1][j] == 0)
                {
                    visited[i - 1][j] = map[i - 1][j];
                }

                // [i][j + 1]
                if (map[i][j + 1] == 1)
                {
                    map[i][j] = prevPosition;
                    if (prevPosition)
                        visited[i][j + 1] = count++;
                }
                if (map[i][j + 1] == 0)
                {
                    visited[i][j + 1] = map[i][j + 1];
                }

                // [i][j - 1]
                if (map[i][j - 1] == 1)
                {
                    map[i][j] = prevPosition;
                    visited[i][j - 1] = map[i][j - 1];
                    if (prevPosition)
                        visited[i][j - 1] = count++;
                }
                if (map[i][j - 1] == 0)
                {
                    visited[i][j - 1] = map[i][j - 1];
                }

            } // map borders check (finished)
              //count++;
        }
    }

    printf("count: %d\n", count);

    if (count > 1000)
    {
        printf("The way couldn't be found\n");
    }
    else
    {
        printf("Matrix of visited cells:\n\n");
        mapPrint(visited);
        //printf("Short way: %d\n", findShortWay(map[7][7]));
    }
    printf("Ways: %d\n", findFreeToGoCells(visited));

    system("pause");
    return 0;
}

int mapZero(int map[WIDTH][WIDTH])
{
    for (int i = 0; i < WIDTH; ++i)
    {
        for (int j = 0; j < HEIGHT; ++j)
        {
            map[i][j] = 0;
        }
    }
}

int mapPrint(int map[WIDTH][HEIGHT])
{
    for (int i = 0; i < WIDTH; ++i)
    {
        for (int j = 0; j < HEIGHT; ++j)
        {
            printf("%2d  ", map[i][j]);
        }
        printf("\n\n");
    }
    printf("\n");
    return 0;
}

int findFreeToGoCells(int map[WIDTH][WIDTH])
{
    int count = 0;
    for (int i = 0; i < WIDTH; ++i)
    {
        for (int j = 0; j < HEIGHT; ++j)
        {
            if (map[i][j] == 1 || map[i][j] == 99) count++;
        }
    }
    return count;
}

这里最短的方法总是15个单元

enter image description here

1 个答案:

答案 0 :(得分:2)

http://localhost:4502/content/mywebsite/somepage/test.jsp 函数的嵌套循环中,表达式main始终为真。

这意味着超出数组范围。

我建议您检查((i >= 0) && (i < WIDTH)) && ((j >= 0) && (j < HEIGHT))的值作为例如i。也许像是

if (map[i + 1][j] == 1)

如果你也为其他地方做了类似的事情(当你if (i < WIDTH - 1 && map[i + 1][j] == 1) { ... } 检查i - 1时),那么你不应该超出界限并且未定义的行为

与上述检查类似的另一种可能性是对i > 0(或i)进行一次检查,然后进行现在的检查。 Sonething喜欢

j