Я полный новичок, поэтому надеюсь, что вы понимаете мой стиль программирования. Я пытаюсь создать программу на C++, которая решает проблему 8 головоломок с использованием алгоритма поиска A * с формулой расстояния Манхэттена в качестве ее эвристического значения. Я завершил настройку, и это два класса, которые я создал.
class State {
public:
int gValue;
int hValue;
int fValue;
int current[3][3];
Pair zeroPos;
State* previous;
State();
State(int[][3], State*);
bool operator<(const State& s) const {
return this->fValue < s.fValue;
}
Pair findIndex(int);
bool updateZeroPos();
void calculateHValue(int[][3]);
void calculateFValue();
void getNeighbors(int, Pair[4]);
void createArrayCopy(int[][3]);
void displayState();
};
class SearchAlgorithm {
public:
vector<State> openList;
vector<State> closeList;
int goalState[3][3];
SearchAlgorithm();
SearchAlgorithm(int[][3], int[][3]);
vector<State> createNextStates(State);
void startSearch();
int isInList(int[][3], int);
bool equal(int[][3], int[][3]);
};
Все начинается с функции startSearch () в классе SearchAlgorithm. Одно из требований этой проблемы - убедиться, что предыдущее состояние не совпадает со следующим, чтобы оно не перемещалось туда и обратно в одном и том же положении. Для этого я планирую передать экземпляр State в функции createNextStates (). При запуске программы никаких проблем не возникло. Но когда он доходит до создания следующих состояний для второго шага, возникает некоторая ошибка, которую я не понимаю. Состояние, полученное функцией createNextStates, не является состоянием, которое я передал при его вызове. Предположительно, он правильно вызывал предыдущее состояние, но когда он входит в функцию createNextStates, State * previous продолжает указывать на себя.
Это мой фрагмент моей функции startSearch
void SearchAlgorithm::startSearch() {
while(!openList.empty()) {
// Get lowest fValue state then pop
State currentState = this->openList.back();
this->openList.pop_back();
if (equal(currentState.current, goalState)) {
currentState.displayState();
break;
}
cout << currentState.fValue << ":" << currentState.gValue << ":" << currentState.hValue << endl;
cout << openList.size() << " NEXT" << endl;
vector<State> neighbors;
neighbors = this->createNextStates(currentState);
И это для моей функции createNextStates:
vector<State> SearchAlgorithm::createNextStates(State stte) {
Pair neighbors[4];
stte.getNeighbors(0, neighbors);
vector<State> stateNeighbors;
for(int i=0; i<4; i++) {
if (neighbors[i].first != -1 && neighbors[i].second != -1) {
int newArray[3][3];
stte.createArrayCopy(newArray);
State newState(newArray, &stte);
newState.current[newState.zeroPos.first][newState.zeroPos.second] = stte.current[neighbors[i].first][neighbors[i].second];
newState.current[neighbors[i].first][neighbors[i].second] = 0;
newState.updateZeroPos();
if (stte.previous == nullptr || !equal(newState.current, stte.previous->current)) {
stateNeighbors.push_back(newState);
}
}
}
return stateNeighbors;
}
Я попытался отладить код с помощью функции отладчика кода VS. Перед вызовом функции это то, что хранится в переменной currentState.
(currentState).previous: 0x00007ffeefbff350
((State *)0x00007ffeefbff350)->previous: 0x0000000000000000
При входе в функцию и передаче currentState в качестве параметра происходит следующее:
(stte).previous: 0x00007ffeefbff350
((State *)0x00007ffeefbff350)->previous: 0x00007ffeefbff350
И это предыдущее продолжается. Он продолжает указывать на себя.
Буду признателен за вашу помощь в этом. Я попытался поискать в другом месте и, похоже, не нашел решения этой ошибки. Заранее спасибо. Простите за длинный пост. И снова извините за не элегантный стиль кодирования. Все еще новичок.
Что вы заметили при пошаговом выполнении кода построчно в отладчике? Были ли какие-то неожиданные смены значений переменных, пропущенные условные переходы?
Да, изображения, которые я опубликовал, являются скриншотами того, что произошло с переменной до и после вызова функции. Кроме того, да, я действительно не привык к отладчику. Тем не менее, все еще учусь.
Хорошо, я ухожу. Я не могу читать картинки.
Извините, я новичок в stackoverflow. Изображения на самом деле являются снимками экрана для переменной, когда я выполнял отладку.
@Boombastic По какой-то причине вы пока не можете публиковать изображения. Однако вы также можете предоставить эту информацию в виде правильно отформатированного текста.
Я понимаю. Очень жаль. Я не привык размещать сообщения в переполнении стека. Я изменю изображения и скопирую вставку.
Изменил изображения уже и напечатал его вместо этого.





Я делаю предположение: вы никогда не использовали отладчик, верно? Если это так, добавьте распечатки начала и конца функции каждый, чтобы вы знали, какие значения вы хотите ввести в функцию и какие они выводятся.