[英]“Wave Algorithm” (based in Lee's Algorithm) in C
我正在寫從A點到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.