我在这个数据结构类中使用堆栈实现了一个迷宫。然而,挑战在于使用此代码中的堆栈来输出迷宫的路径,包括当它到达无法再移动的坐标时返回到它来的方式的过程。我试着用ChatGPT解决它,但我对结果不满意,所以我像这样寻求帮助。
这是我的代码。
#define MAZE_SIZE 10
#define MAX_STACK_SIZE 100
#include <stdio.h>
int back_count ;
typedef struct {
short r ;
short c ;
} element;
typedef struct {
int top ;
element data[MAX_STACK_SIZE];
} StackType ;
void init_stack(StackType *s) {
s->top = -1 ;
}
int is_empty(StackType *s) {
return (s->top == -1);
}
int is_full(StackType *s) {
return (s->top == MAX_STACK_SIZE - 1) ;
}
void push(StackType *s, element item) {
if (is_full(s)) {
fprintf(stderr, "Stack Full") ;
return;
}
else {
s->data[++(s->top)] = item ;
}
}
element pop(StackType *s) {
if (is_empty(s)) {
fprintf(stderr, "Stack Empty") ;
element err = {-1, -1};
return err;
}
else {
return (s->data[(s->top)--]) ;
}
}
element here = {1, 0}, entry = {1, 0};
char maze[MAZE_SIZE][MAZE_SIZE] = {
{'1','1','1','1','1','1','1','1','1','1'},
{'e','1','0','1','0','0','0','1','0','1'},
{'0','0','0','1','0','0','0','1','0','1'},
{'0','1','0','0','0','1','1','0','0','1'},
{'1','0','0','0','1','0','0','0','0','1'},
{'1','0','0','0','1','0','0','0','0','1'},
{'1','0','0','0','0','0','1','0','1','1'},
{'1','0','1','1','1','0','1','1','0','1'},
{'1','1','0','0','0','0','0','0','0','x'},
{'1','1','1','1','1','1','1','1','1','1'}
} ;
void push_loc(StackType *s, int r, int c) {
if(r<0 || c<0) {
return ;
}
if(maze[r][c] != '1' && maze[r][c] != '.') {
element tmp ;
tmp.r = r ;
tmp.c = c ;
push(s, tmp) ;
}
}
void maze_print(char maze[MAZE_SIZE][MAZE_SIZE]) {
printf("\n") ;
for(int r=0; r<MAZE_SIZE; r++) {
for(int c=0; c<MAZE_SIZE; c++) {
printf("%c", maze[r][c]) ;
}
printf("\n") ;
}
}
int backcount(int r, int c) {
if ((maze[r + 1][c] == '1' || maze[r + 1][c] == '.') && (maze[r - 1][c] == '1' || maze[r - 1][c] == '.') && (maze[r][c + 1] == '1' || maze[r][c + 1] == '.') && (maze[r][c - 1] == '1' || maze[r][c - 1] == '.'))
{
back_count++;
}
return back_count;
}
int main(void) {
int r, c ;
StackType s ;
init_stack(&s) ;
here = entry ;
while(maze[here.r][here.c] != 'x') {
r = here.r ;
c = here.c ;
maze[r][c] = '.' ;
maze_print(maze) ;
push_loc(&s, r-1,c) ;
push_loc(&s, r+1,c) ;
push_loc(&s, r,c-1) ;
push_loc(&s, r,c+1) ;
backcount(r, c) ;
if(is_empty(&s)) {
printf("Fail\n") ;
return 0 ;
}
else {
here = pop(&s) ;
}
}
printf("Success\n") ;
printf("Back count : %d\n", backcount(r, c)) ;
return 0 ;
}
我做了另一个堆栈来推动所有的移动路径并打印出来,输出是这个迷宫的(1,4)到(4,3)。
这是将产生我想要的输出的路径。
Path to exit :
(1, 0)
(2, 0)
(2, 1)
(2, 2)
(2, 3)
(3, 3)
(3, 4)
(2, 4)
(2, 5)
(2, 6)
(1, 6)
(1, 5)
(1, 4)
(1, 5)
(1, 6)
(2, 6)
(2, 5)
(2, 4)
(3, 4)
(3, 3)
(4, 3)
(4, 2)
(4, 1)
(5, 1)
(5, 2)
(5, 3)
(6, 3)
(6, 4)
(6, 5)
(7, 5)
(8, 5)
(8, 6)
(8, 7)
(8, 8)
1条答案
按热度按时间2izufjch1#
澄清一下,你的目标是解决迷宫,同时也提供算法找到的路径,对吗?
现在,当你站在一个单元格上时,你正在存储堆栈中所有相邻的单元格。这对于保存尚未探索的单元格列表很好,但对于存储到目前为止所采用的路径则不太好。
例如,假设你有这个迷宫:
出口就在入口旁边。使用您的方法,在循环的第一次迭代中,您将把
e
旁边的所有tile放入堆栈中,如下所示:然后你会弹出堆栈的顶部,这是入口右边的单元格,你会看到它是出口,然后你的程序就完成了。
但堆栈的状态仍然是这样的:
如果你用视觉的方式来展示它,就是:
堆栈根本不反映让你走到最后的路径。相反,它反映了所有的瓷砖,你 * 没有 * 访问,以找到结束。
相反,尝试颠倒使用堆栈的方式。不要存储所有你没有访问过的单元格,而是尝试存储所有你访问过的单元格。这样,您就可以使用堆栈来存储到达当前位置的路径。
这大概就是你的main函数应该看起来的样子,我还没有测试它的语法错误,但是注解应该清楚地说明每一步发生了什么:
我刚刚意识到你(和我)的代码还有一些其他问题,当你检查一个瓦片的邻居时,你没有检查这些瓦片是否在迷宫的边界内(例如,当我们查看一个单元的左侧时,数组的索引-1-你的例子中的入口点有这个问题)。这应该不会太难修复,你只需要记住这样做,因为C不会给予你任何警告,当它发生时,它只是程序可能会segfault或你的结果变得胡言乱语。