簡體   English   中英

C語言中的“波動算法”(基於李氏算法)

[英]“Wave Algorithm” (based in Lee's Algorithm) in C

我正在寫從A點到B點的最短程序計算。我有一個帶有值的映射(矩陣):

  • 0是塊(牆,無法通過);
  • 1是自由方式(您可以通過);
  • 11是點A(起點);
  • 22是點B(終點)。

我讀過幾篇文章,它應該如何工作,並試圖實現自己的版本,但堆積如山。

在下面的代碼中,我聲明了2個數組:一個帶有Map的數組和一個運行演示了訪問點的程序時“訪問過”的已更改數組。

我在4個方向(不是對角線)上檢查了1或0的單元格。如果它是1(可能通過),則將計數器增加1。因為不要計算上一個單元格,因此我試圖避免這種情況。

結果,我想看到帶有幾行的“已訪問”矩陣,該矩陣顯示了到達點B的方式(1、2、3,... 15)。

現在,我的地圖看起來不正確,甚至沒有關閉。

我在算法中錯過了什么,應該考慮什么以及如何修復程序?

謝謝。

PS我寫了一些函數來實現一個具有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個單元格

在此處輸入圖片說明

main函數的嵌套循環中,表達式((i >= 0) && (i < WIDTH)) && ((j >= 0) && (j < HEIGHT)) 始終為真。

這意味着您超出數組的范圍。

我建議您在做if (map[i + 1][j] == 1)的過程中檢查i值。 也許像

if (i < WIDTH - 1 && map[i + 1][j] == 1) { ... }

如果在其他地方也執行類似操作(對於i - 1檢查i > 0 ),則不應超出范圍並具有未定義的行為

與上述檢查類似的另一種可能性是,對i (或j )進行一次檢查,然后進行您現在擁有的檢查。 音色像

if (i < WIDTH - 1)
{
    if (map[i + 1][j] == 1) { ... }

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM