Главная arrow С++ (часть 2) arrow Поиск потерянных ключей

Поиск потерянных ключей

Единственно подходящим завершением главы о поиске решений представляется создание программы поиска ключей от машины из первого примера. В приведенном в листинге 7.8 коде использованы те же технические приемы, что и программах поиска маршрута между городами, поэтому он дан без последующих пояснений.
{ Листинг 7.8. Поиск потерянных ключей
#include <ioscream> #include <stack> #include <string> #include <vector>
using namespace std;
// Информация о комнате, struct Roomlnfo {
string from,-
string to;
bool skip;
RoomlnfoO  { from - "";
to =   "";
skip = false;
}
. Roamlnfо(string f. string t)  { from = f; to = t; skip = false;
}
};
// Ищет ключи, используя поиск в глубину, class Search {
// Этот вектор содержит информацию о комнатах.
vector<RoomInfo> rooms;
// Этот стек применяется для возврата. stack<RoamInfo> btStack;
// Возвращает true, если существует путь между
// from и to. Возвращает false в противном случае.
bool match(string from, string to);
// При заданном from находит любой путь. // Возвращает true, если путь найден, // и false — в противном случае, bool find(string from, Roomlnfo &f);
public:
// Помещает сведения о комнатах в базу данных.
void addroom(string from, string to)
{
rooms.push_back(Roomlnfo(from, to));
}
// Показывает пройденный маршрут. void route();
// Определяет, есть ли путь между from и to. void findkeys(string from, string to);
// Возвращает true, если ключи были найдены, bool keysfound()  {
return !btStack.empty();
}
};
// Показывает маршрут, void Search::route() {
stack<RoomInfo> rev; Roomlnfo f;
// Меняет порядок стека на обратный для отображения маршрута, while(!btStack.empty())  (
f = btStack.topO ;
rev.push(f);
btStack.pop4);
}
// Отображает маршрут, while(!rev.empty())  {
f = rev.top();
rev.pop() ;
cout « f.from « " to ";
}
cout « f.to « endl;
}
// Возвращает true, если существует путь между
// from и to. Возврашает false в противном случае.
bool Search::match(string from, string to)
{
for(unsigned i=0; i < rooms.size(); i++)  { if(rooms[i].from == from &&
rooms[i].to == to && !rooms[i].skip)
{
rooms[i].skip = true; // предотвращает повторное использование return true;
}
}
return false; //не найлен
}
// При заданном from находит какой-нибудь путь.
// Возвращает true, если путь найден,
//и false — в противном случае.
bool Search::find(string from, Roomlnfo &f)
{
for(unsigned i=0; i < rooms.size(); i++)  {
if (rooms [i]. from == from && !rooms [i] .skip)  { f = rooms [i];
rooms[i].skip = true; // предотвращает повторное использование return true;
}
}
return false;
}
// Ищет ключи.
void Search::findkeys(string from, string to) {
Roomlnfo f;
// Проверяет, найдены ли ключи, if (match (from, to))  {
btStack.push(Roomlnfo(from, to)); •      return; }
// Проверяет другую комнату, if(find(from, f))  {
btstack.push(Roomlnfo(from, to));
findkeys(f.to, to);
}
else i f(!btStack.empcy())  {
// Возвращается и пробует другой путь.
f = btStack.top() ; btStack.popO ; findkeys(f.from, f.to);
}
}
int main() Search ob;
// Добавляет комнаты в базу данных, ob.addroom ("front_door",  "lrn); ob.addroom ("lrn,  "bath"); ob.addroom ("lrn,  "hall"); ob.addroom("hall",  "bdl"); ob.addroom("hall",  "bd2"); ob.addroom ("hall",  "mb"); ob.addroom("lr",  "ki tcheh"); ob.addroom ("ki tchen",  "keys");
// Ищет ключи.
ob. f indkeys (" f ront_door",  " keys ") ; // Если ключи найдены, показывает путь, if(ob.keysfound()) ob.route();
return 0;
}