递归的迷宫遍历输出每一条完整的路径
Maze traversal with recursion what prints every full path
我正在尝试遍历迷宫并产生所有有效路径。迷宫总是从s开始,所有出口都可以在最右边的任何地方墙。顶墙和底墙始终是一排排的#符号。我只能移动相邻的包含非#字符的正方形
这是一个迷宫的例子。
######
Sa#hln
#bdp##
##e#ko
#gfij#
######
这是应该打印出来的内容:
S, a, b, d, e, f, i, j, k, o
S, a, b, d, p, h, l, n
我得到S a b d e f I j k o p h l n
这是第一条路径,以及它分叉的第二条路径的一半。我将感激任何帮助。谢谢你。
#include <fstream>
#include <string>
#include <iostream>
#include <stack>
using namespace std;
//std::ifstream file("maze.txt");
string str;
string file_contents;
fstream in("maze.txt");
//check if char is not #
bool characterAt(string maze[][6], int r, int c){
if (maze[r][c] == "#"){
return false;
}
return true;
}
//check if I have been there before
bool backTrack(bool maze[][6], int r, int c){
if (maze[r][c] == false){
return true;
}
return false;
}
//check if my move is in bounds.
bool validMove(int r, int c){
if (r - 1 < 0 || r + 1 > 6 ||
c - 1 < 0 || c + 1 > 6){
return false;
}
return true;
}`
//check if there is a next move
bool thereIsNextMove(string maze[][6], bool bmaze[][6], int rows, int columns){
if (validMove(rows - 1, columns) && backTrack(bmaze, rows - 1, columns) && characterAt(maze, rows - 1, columns) ||
validMove(rows + 1, columns) && backTrack(bmaze, rows + 1, columns) && characterAt(maze, rows + 1, columns) ||
validMove(rows, columns - 1) && backTrack(bmaze, rows, columns - 1) && characterAt(maze, rows, columns - 1) ||
validMove(rows, columns + 1) && backTrack(bmaze, rows, columns + 1) && characterAt(maze, rows, columns + 1)){
return true;
}
return false;
}
void generate_all_paths(string maze[][6], bool bmaze[][6], int rows, int columns){
int y = rows;
int x = columns;
string path = maze[y][x];
stack<string> s;
if (thereIsNextMove(maze, bmaze, y, x) || x == 5){
s.push(path);
cout << s.top();
s.pop();
}
if (validMove(y - 1, x) && characterAt(maze, y - 1, x) && backTrack(bmaze, y - 1, x)){
bmaze[y][x] = true;
generate_all_paths(maze, bmaze, y - 1, x);
}
if (validMove(y + 1, x) && characterAt(maze, y + 1, x) && backTrack(bmaze, y + 1, x)){
bmaze[y][x] = true;
generate_all_paths(maze, bmaze, y + 1, x);
}
if (validMove(y, x - 1) && characterAt(maze, y, x - 1) && backTrack(bmaze, y, x - 1)){
bmaze[y][x] = true;
generate_all_paths(maze, bmaze, y, x - 1);
}
if (validMove(y, x + 1) && characterAt(maze, y, x + 1) && backTrack(bmaze, y, x + 1)){
bmaze[y][x] = true;
generate_all_paths(maze, bmaze, y, x + 1);
}
}
int main(){
while (getline(in, str))
{
file_contents += str;
//file_contents.push_back('n');
}
string maze[6][6];
for (int row = 0; row < 6; row++){
for (int col = 0; col < 6; col++){
char mazeChar = file_contents.at(6 * row + col);
maze[row][col] = mazeChar;
}
}
bool bmaze[6][6];
for (int brow = 0; brow < 6; brow++){
for (int bcol = 0; bcol < 6; bcol++){
bmaze[brow][bcol] = false;
}
}
string path;
generate_all_paths(maze, bmaze, 1, 0);
int age;
cin >> age;
return 0;
}
这里'generate_all_paths'函数中的堆栈根本没有被使用。在给定的实现中,堆栈在任何给定时间最多只包含一个元素。与其每次找到路径都打印路径,不如让堆栈保持全局,并将新路径推送到它,然后在到达目的地时立即打印整个堆栈,然后在函数结束时从堆栈中删除该元素,就像你在穿越迷宫时走回分叉点一样。
#include <fstream>
#include <string>
#include <iostream>
#include <stack>
using namespace std;
//std::ifstream file("maze.txt");
string str;
string file_contents;
fstream in("maze.txt");
stack<string> s;
//check if char is not #
bool characterAt(string maze[][6], int r, int c){
if (maze[r][c] == "#"){
return false;
}
return true;
}
//check if I have been there before
bool backTrack(bool maze[][6], int r, int c){
if (maze[r][c] == false){
return true;
}
return false;
}
//check if my move is in bounds.
bool validMove(int r, int c){
if (r - 1 < 0 || r + 1 > 6 ||
c - 1 < 0 || c + 1 > 6){
return false;
}
return true;
}
//check if there is a next move
bool thereIsNextMove(string maze[][6], bool bmaze[][6], int rows, int columns){
if (validMove(rows - 1, columns) && backTrack(bmaze, rows - 1, columns) && characterAt(maze, rows - 1, columns) ||
validMove(rows + 1, columns) && backTrack(bmaze, rows + 1, columns) && characterAt(maze, rows + 1, columns) ||
validMove(rows, columns - 1) && backTrack(bmaze, rows, columns - 1) && characterAt(maze, rows, columns - 1) ||
validMove(rows, columns + 1) && backTrack(bmaze, rows, columns + 1) && characterAt(maze, rows, columns + 1)){
return true;
}
return false;
}
template < typename T > void print( const std::stack<T>& stk )
{
struct cheat : std::stack<T> { using std::stack<T>::c ; } ;
const auto& seq = static_cast< const cheat& >(stk).c ;
for( const auto& v : seq ) std::cout << v << ' ' ;
std::cout << 'n' ;
}
void generate_all_paths(string maze[][6], bool bmaze[][6], int rows, int columns){
int y = rows;
int x = columns;
string path = maze[y][x];
bool pushed = false;
if (thereIsNextMove(maze, bmaze, y, x)){
s.push(path);
pushed = true;
}
if (x == 5){
s.push(path);
pushed=true;
print(s);//printing the entire stack once a path has been found
}
if (validMove(y - 1, x) && characterAt(maze, y - 1, x) && backTrack(bmaze, y - 1, x)){
bmaze[y][x] = true;
generate_all_paths(maze, bmaze, y - 1, x);
}
if (validMove(y + 1, x) && characterAt(maze, y + 1, x) && backTrack(bmaze, y + 1, x)){
bmaze[y][x] = true;
generate_all_paths(maze, bmaze, y + 1, x);
}
if (validMove(y, x - 1) && characterAt(maze, y, x - 1) && backTrack(bmaze, y, x - 1)){
bmaze[y][x] = true;
generate_all_paths(maze, bmaze, y, x - 1);
}
if (validMove(y, x + 1) && characterAt(maze, y, x + 1) && backTrack(bmaze, y, x + 1)){
bmaze[y][x] = true;
generate_all_paths(maze, bmaze, y, x + 1);
}
if(pushed){
s.pop();//removing the element from the stack like how you walk back to fork point
}
}
int main(){
while (getline(in, str))
{
file_contents += str;
//file_contents.push_back('n');
}
string maze[6][6];
for (int row = 0; row < 6; row++){
for (int col = 0; col < 6; col++){
char mazeChar = file_contents.at(6 * row + col);
maze[row][col] = mazeChar;
}
}
bool bmaze[6][6];
for (int brow = 0; brow < 6; brow++){
for (int bcol = 0; bcol < 6; bcol++){
bmaze[brow][bcol] = false;
}
}
string path;
generate_all_paths(maze, bmaze, 1, 0);
int age;
cin >> age;
return 0;
}
PS -我已经添加了一个名为print的函数来打印堆栈
相关文章:
- 如何在 c++ 中确定一条指令(以字节为单位)在哪里结束,另一条指令从哪里开始?
- 如何在 Win32 中用一条线连接 2 个文本框?
- C++ 如何在同一行中和在一条线上?
- 如何在SDL2窗口上使用Cairo绘制一条白色直线
- 在Opengl中绘制一条不显示C++的线
- 为什么当 while 循环中的 if 条件变为 false 时,我的函数不输出最后一条语句?
- x86 - 为什么编译器在下一条指令中插入看似毫无意义的JMP?
- CMake似乎忽略了一条线
- 在C 中使用Legacy OpenGL(即时模式)绘制一条厚线
- 在图像标签上画一条线并计算距离
- switch 语句结束和下一条语句之间的时间是否具有确定性(与路径无关)
- 如何在OMNET++中收到来自前一个模块的所有消息后将一条消息发送到下一个模块
- 一条线和两行声明之间的差异
- C++ OpenCV:检测两条线而不是一条线(Canny & findContours)
- 如何在C++中将边列表转换为邻接矩阵,其中包含连接到顶点的边数而不是一条边?
- 为什么 fstream 打印出文件的最后一条记录
- 使用递归在迷宫中找到一条路径
- 递归的迷宫遍历输出每一条完整的路径
- 在迷宫中找到一条最短路径,然后行动
- 如何从另一条路径中减去一条路径