Advertisement
chevengur

СПРИНТ № 5 | Итераторы | Урок 7: Стандартные алгоритмы — рекурсия 3/3

Jan 15th, 2024
813
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.02 KB | None | 0 0
  1. #include <iostream>
  2. #include <stdexcept>
  3. #include <vector>
  4.  
  5. using namespace std;
  6.  
  7. class Tower {
  8. public:
  9.     // конструктор и метод SetDisks нужны, чтобы правильно создать башни
  10.     Tower(int disks_num) {
  11.         FillTower(disks_num);
  12.     }
  13.  
  14.     int GetDisksNum() const {
  15.         return disks_.size();
  16.     }
  17.  
  18.     void SetDisks(int disks_num) {
  19.         FillTower(disks_num);
  20.     }
  21.  
  22.     // добавляем диск на верх собственной башни
  23.     // обратите внимание на исключение, которое выбрасывается этим методом
  24.     void AddToTop(int disk) {
  25.         int top_disk_num = disks_.size() - 1;
  26.         if (0 != disks_.size() && disk >= disks_[top_disk_num]) {
  27.             throw invalid_argument("Невозможно поместить большой диск на маленький");
  28.         } else {
  29.             disks_.push_back(disk); // заполняем вектор башни (добавляем диск)
  30.             // допишите этот метод и используйте его в вашем решении
  31.         }
  32.     }
  33.  
  34.     void MoveDisks(int disks_num, Tower& destination, Tower& buffer) {
  35.         if (disks_num > 0) {
  36.             MoveDisks(disks_num - 1, buffer, destination);
  37.             destination.AddToTop(disks_.back());
  38.             this->disks_.pop_back();
  39.             buffer.MoveDisks(disks_num - 1, destination, *this);
  40.             // действия из шага рекурсии
  41.         }
  42.     }
  43.    
  44.  
  45.     // вы можете дописывать необходимые для вашего решения методы
  46.  
  47. private:
  48.     vector<int> disks_;
  49.  
  50.     // используем приватный метод FillTower, чтобы избежать дубликации кода
  51.     void FillTower(int disks_num) {
  52.         for (int i = disks_num; i > 0; i--) {
  53.             disks_.push_back(i);
  54.         }
  55.     }
  56.  
  57.     // disks_num - количество перемещаемых дисков
  58.     // destination - конечная башня для перемещения
  59.     // buffer - башня, которую нужно использовать в качестве буфера для дисков
  60.    
  61. };
  62.  
  63. void SolveHanoi(vector<Tower>& towers) {
  64.     int disks_num = towers[0].GetDisksNum();
  65.      // запускаем рекурсию
  66.      // просим переложить все диски на последнюю башню
  67.      // с использованием средней башни как буфера
  68.     towers[0].MoveDisks(disks_num, towers[2], towers[1]);
  69.  }
  70.  
  71. int main() {
  72.     int towers_num = 3;
  73.     int disks_num = 3;
  74.     vector<Tower> towers;
  75.     // добавим в вектор три пустые башни
  76.     for (int i = 0; i < towers_num; ++i) {
  77.         towers.push_back(0);
  78.     }
  79.     // добавим на первую башню три кольца
  80.     towers[0].SetDisks(disks_num);
  81.     SolveHanoi(towers);
  82. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement