У меня есть проект, который получает лабиринт через txt файл, и я должен его решить. Единственными трудными спецификациями для его решения являются: Никакой другой двумерный массив (No Copy, No Bool).
Поэтому я использую стеки и backtracking, чтобы решить эту проблему. Я использую два стека, один для копирования посещенных комнат, а другой - для копирования пути. Но дело в том, что когда я вернусь к основной функции, два стека только получили последнюю позицию, которую они получили в лабиринте. Так что моя проблема, просто последняя позиция в моих стопках.
Когда я нахожусь в функции Backtracking Function, есть еще одна функция, которая проверяет, был ли я раньше в этой позиции, я тестирую стек, о котором я упоминал ранее, и работает отлично (стек, который сохраняет посещаемые комнаты), я напечатал все значения этого стека,
Я не знаю, почему основная функция не может получить полный стек (по крайней мере, для посещенных комнат), а стек стека вообще не работает.
bool path(ColaD* colaDG, Node* temp, PileD* pileDG)
{
if (temp->row == colaDG->end->row && temp->col == colaDG->end->col)
return true;
if (check(pileDG, temp) || mat[temp->row][temp->col] == 1)
{
// call check function
return false;
}
pileDG->push(*temp);
if (temp->row != 0)
{
temp->row -= 1;
colaDG->push(*temp);
if (path(colaDG, temp, pilaDG))
{
return true;
}
temp->row += 1;
}
if (temp->row != n - 1)
{
temp->row += 1;
colaDG->push(*temp);
if (path(colaDG, temp, pilaDG))
{
return true;
}
temp->row -= 1;
}
if (temp->col != 0)
{
temp->col -= 1;
colaDG->push(*temp);
if (path(colaDG, temp, pilaDG))
{
return true;
}
temp->col += 1;
}
if (temp->col != m - 1)
{
temp->col += 1;
colaDG->push(*temp);
if (path(colaDG, temp, pilaDG))
{
return true;
}
temp->col -= 1;
}
return false;
}
bool check(PileD* pileDG, Node* temp)
{
// Function to check visited rooms
bool flag = false;
Node * recor;
recor = new Node();
recor = pileDG->top;
while (recor != NULL)
{
if (recor->row == temp->row && recor->col == temp->col)
{
// if already here, return true
flag = true;
break;
}
else
recor = recor->pre;
}
return flag;
}
Я знаю, но я не знаю, как это сделать.
Я думаю об использовании графика для его решения, но я не знаю, как реализовать график вообще. Извините за мой английский, я не являюсь носителем английского языка. Я попытался изменить некоторые слова на код, потому что некоторые слова были на испанском языке. Любая помощь будет большой. И извините за весь код в файле.cpp, я просто тестирую, настоящий проект будет другим.
Полный код:
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
using namespace std;
int n=0,m=0;
int **mat;
class Node{
public:
Node(){pre=NULL;}
int row;
int col;
Node *pre;
};
class ColaD{
public:
ColaD(){fin=fte=end=NULL;}
void push(Nodo xdato);
void pop();
Node *fte,*fin,*end;
};
void ColaD::push(Node xdato){
Node *nuevo;
nuevo = new Node();
if(nuevo){
(*nuevo)= xdato;
nuevo->pre = NULL;
if(!fte)
fte = nuevo;
else
fin->pre=nuevo;
fin = nuevo;
}
}
void ColaD::pop(){
Node *elim;
if(fte){
elim = fte;
if(fte==fin)
fte = fin = NULL;
else
fte = fte->pre;
delete(elim);
}
}
class PileD{
public:
PileD(){tope=NULL;}
void push(Node xdato);
void pop();
Node *tope;
};
void PilaD::push(Node xdato){
Node *nuevo;
nuevo = new Node;
if(nuevo){
(*nuevo)=xdato;
nuevo->pre=tope;
tope=nuevo;
}
}
void PileD::pop(){
Node *aux;
if(tope){
aux=tope;
tope=tope->pre;
free(aux);
}
}
void tamMat(); //read the size of the maze given by a txt file
void loadM(); //once i know the size, and the bi dimensional is created I set the values to de bi dimensional A.
void printM(); //Just check the values
bool path(ColaD *colaDG,Node *temp,PileD *pileDG);
bool check(PileD *pileDG,Node *temp);
int main(int argc, char const *argv[])
{
ColaD *colaDG;
Node *inicio;
PileD *pileDG;
tamMat(); //Read the size
mat = new int*[n];
for(int i=0;i<n;i++)
mat[i]=new int[m];
loadM(); //Set values given from the file
colaDG = new ColaD();
pileDG = new PileD();
inicio = new Node();
inicio->row=0; //Proyect says, the start of the maze is in the first row of the maze
for(int j=0;j<m;j++)
if(mat[0][j]!=1){
inicio->col=j; //Found the position in the row
break;
}
colaDG->end = new Nodo();
colaDG->end->row=n-1; //End position is in the last row
for(int j=0;j<m;j++)
if(mat[n-1][j]!=1){
colaDG->end->col=j; //Found the position
break;
}
bool b = path(colaDG,inicio,pilaDG); //call my backtrack function
getchar();
/* CODE TO CHECK visited Rooms
Nodo *temp = new Nodo();
temp=pileDG->tope;
while(temp!=NULL){
cout << temp->row <<" "<<temp->col << endl;
getchar();
temp->pre;
}
*/
getchar();
return 0;
}
void tamMat(){
fstream inFile;
int num;
n=m=0;
inFile.open("mat.txt",ios::in);
string line;
getline(inFile,line);
stringstream temp(line);
while(temp>> num)
m++;
n++;
while(getline(inFile,line))
n++;
inFile.close();
}
void loadM(){
fstream inFile;
inFile.open("mat.txt",ios::in);
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
inFile >> mat[i][j];
inFile.close();
}
void printM(){
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
if(mat[i][j]!=1)
cout << " ";
else
cout << mat[i][j];
cout << " ";
}
cout << endl;
}
}
bool path(ColaD *colaDG,Node *temp,PileD *pileDG){
if(temp->row==colaDG->end->row && temp->col==colaDG->end->col) return true;
if(check(pileDG,temp) || mat[temp->row][temp->col]==1){
return false;
}
pileDG->insertar(*temp);
if(temp->row!=0){
temp->row-=1;
colaDG->insertar(*temp);
if(path(colaDG,temp,pileDG)){
return true;
}
temp->row+=1;
}
if(temp->row!=n-1){
temp->row+=1;
colaDG->insertar(*temp);
if(path(colaDG,temp,pileDG)){
return true;
}
temp->row-=1;
}
if(temp->col!=0){
temp->col-=1;
colaDG->insertar(*temp);
if(path(colaDG,temp,pileDG)){
return true;
}
temp->col+=1;
}
if(temp->col!=m-1){
temp->col+=1;
colaDG->insertar(*temp);
if(path(colaDG,temp,pileDG)){
return true;
}
temp->col-=1;
}
return false;
}
bool check(PileD *pileDG,Node *temp){
bool flag=false;
Node *recor;
recor = new Node();
recor = pileDG->tope;
while(recor!=NULL){
if(recor->row==temp->row && recor->col==temp->col){
flag=true;
break;
}
else
recor=recor->pre;
}
return flag;
}
Файл Maze mat.txt.
0 0 0 1 1 1 1 1 1 1
1 1 0 1 0 5 1 1 0 1
1 1 6 1 7 1 1 1 0 1
1 1 0 1 0 1 0 0 0 1
1 0 9 0 0 1 0 1 0 1
1 8 1 1 0 1 6 1 0 1
1 0 1 1 0 1 0 1 5 1
1 0 1 1 0 1 0 1 0 1
1 0 0 1 0 0 0 1 7 1
1 1 1 1 1 1 1 1 0 1
1=Walls / 0=Free Space / Other numbers = Bonus
Есть много проблем с вашим кодом, некоторые из них важны, некоторые из них - проблемы с эффективностью. Основная проблема, которую я вижу сейчас, заключается не в коде анализа, а в коде диагностики.
Посмотрите на часть в комментарии:
/* CODE TO CHECK visited Rooms */
Nodo *temp = new Nodo();
temp=pileDG->tope;
while(temp!=NULL){
cout << temp->row <<" "<<temp->col << endl;
getchar();
temp->pre;
}
Последняя строка перед закрывающей скобкой
temp->pre;
Он просто считывает поле pre
из *temp
объекта, но не использует это значение - temp
переменная не изменяется, поэтому программа остается в цикле навсегда, снова и снова печатать одну и ту же часть данных.
Я полагаю
temp = temp->pre;
это то, что вы имели в виду.
В любом случае такие циклы легче писать и читать, если вы используете for
вместо while
:
/* CODE TO CHECK visited Rooms */
for( Nodo *temp=pileDG->tope; temp!=NULL; temp=temp->pre){
cout << temp->row <<" "<<temp->col << endl;
getchar();
}
После его замены вы, возможно, увидите (некоторые) другие проблемы с кодом. Например, вы можете найти слишком много "посещенных" позиций в напечатанном виде.
Что происходит в этой части кода?
Node * recor;
recor = new Node();
recor = pileDG->top;
Разве новый узел не потерян навсегда...?
Кажется, вы помещаете каждую новую точку в стек colaDG
. Однако я не вижу, где вы удаляете точки, когда вы отскакиваете от тупиковых путей...
recor
для хранения указателя на объект класса Node
; вторая строка создает новый объект Node и сохраняет указатель на этот объект в переменной recor
; третья строка считывает указатель на какой-либо другой объект Node
из переменной-члена pileDG->top
и сохраняет указатель на ту же самую recor
переменной. Таким образом, указатель на вновь созданный объект Node
перезаписывается. Поскольку он не был сохранен в каком-либо другом месте, программа больше не может получить доступ к созданному объекту Node
- он потерян.