首页 > 解决方案 > 河内印刷塔(带台阶和塔)

问题描述

所以,我正在尝试制作一个递归函数来解决河内塔。我相信我掌握了循环的要点,并且能够打印出移动的内容以及 3 个塔的简单文本图形。

这是我的代码:它包括一个 Tower 类,我制作它以便能够将三个塔打印到控制台上。

#include <iostream>
#include <string>
#include <vector>
#include <cmath>

using namespace std;

class Tower
{
private:
    string name;
    vector<string> contents;

public:
    Tower(string n)
    {
        this->name = n;
    }

    void setName(string n)
    {
        this->name = n;
    }

    string getName()
    {
        return this->name;
    }

    void setVectorSize(int size)
    {
        contents.resize(size);
    }

    void pushDisk(string val)
    {
        this->contents.push_back(val);
    }

    void popDisk()
    {
        this->contents.pop_back();
    }

    string printTower()
    {
        string output = "Tower " + this->name + ": ";

        for (string disk : contents)
        {
            output += disk + " ";
        }

        return output;
    }

    void clearContents()
    {
        contents.clear();
    }

};

void towersOfHanoi(int, Tower*, Tower*, Tower*);
string orderedTowers(Tower*, Tower*, Tower*);

int main()
{
    int diskNum;
    char ans;
    bool run = true;

    auto tower1 = new Tower("1");
    auto tower2 = new Tower("2");
    auto tower3 = new Tower("3");

    do
    {
        cout << "How many disks would you like to use (positive integers only): ";
        cin >> diskNum;
        while (diskNum < 1)
        {
            cout << "\nThe number of disks must be a positive integer.\n"
                << "How many disks would you like to use (positive integers only): ";
            cin >> diskNum;
        }

        cout << endl << pow(2, diskNum) - 1 << " moves are needed to solve for " << diskNum << "  disk(s).\n";

        //tower1->setVectorSize(diskNum);
        //tower2->setVectorSize(diskNum);
        //tower3->setVectorSize(diskNum);

        for (int i = diskNum; i > 0; i--)
        {
            string c = to_string(i);
            tower1->pushDisk(c);
        }

        cout << orderedTowers(tower1, tower2, tower3) << endl;

        system("pause");

        towersOfHanoi(diskNum, tower1, tower2, tower3);

        cout << "\nWould you like to run again (Y/N): ";
        cin >> ans;

        if (toupper(ans) == 'Y')
        {
            run = true;
            system("cls");

            tower1->clearContents();
            tower2->clearContents();
            tower3->clearContents();
        }

        else if (toupper(ans) == 'N')
        {
            run = false;
        }

    } while (run == true);

    return 0;
}

void towersOfHanoi(int disks, Tower* t1, Tower* t2, Tower* t3)
{
    if (disks != 0)
    {
        towersOfHanoi(disks - 1, t1, t3, t2);

        cout << "\nMove disk " << disks << " from tower " << t1->getName() << " to tower " << t2->getName() << endl;

        t1->popDisk();
        t2->pushDisk(to_string(disks));

        cout << orderedTowers(t1, t2, t3) << endl;

        system("pause");

        towersOfHanoi(disks - 1, t2, t1, t3);
    }
}

string orderedTowers(Tower* t1, Tower* t2, Tower* t3)
{
    string output;

    if (t1->getName() == "1")
        output += t1->printTower() + "\n";

    else if(t2->getName() == "1")
        output += t2->printTower() + "\n";

    else if (t3->getName() == "1")
        output += t3->printTower() + "\n";



    if (t1->getName() == "2")
        output += t1->printTower() + "\n";

    else if (t2->getName() == "2")
        output += t2->printTower() + "\n";

    else if (t3->getName() == "2")
        output += t3->printTower() + "\n";



    if (t1->getName() == "3")
        output += t1->printTower() + "\n";

    else if (t2->getName() == "3")
        output += t2->printTower() + "\n";

    else if (t3->getName() == "3")
        output += t3->printTower() + "\n";


    return output;
}

但是,我在实际解决难题的程序中遇到了一个问题:有时我移动磁盘时,某个磁盘的数量会减一。

例如,3 个磁盘的输出将是:

How many disks would you like to use (positive integers only): 3

7 moves are needed to solve for 3  disk(s).
Tower 1: 3 2 1
Tower 2:
Tower 3:

Press any key to continue . . .

Move disk 1 from tower 1 to tower 2
Tower 1: 3 2
Tower 2: 1
Tower 3:

Press any key to continue . . .

Move disk 2 from tower 1 to tower 3
Tower 1: 3
Tower 2: 1
Tower 3: 2

Press any key to continue . . .

Move disk 1 from tower 3 to tower 1
Tower 1: 3 1
Tower 2: 1
Tower 3:

Press any key to continue . . .

Move disk 3 from tower 1 to tower 2
Tower 1: 3
Tower 2: 1 3
Tower 3:

Press any key to continue . . .

Move disk 1 from tower 2 to tower 3
Tower 1: 3
Tower 2: 1
Tower 3: 1

Press any key to continue . . .

Move disk 2 from tower 2 to tower 1
Tower 1: 3 2
Tower 2:
Tower 3: 1

Press any key to continue . . .

Move disk 1 from tower 1 to tower 2
Tower 1: 3
Tower 2: 1
Tower 3: 1

Press any key to continue . . .

解决这个难题确实需要最少的移动量,但看看输出,显然不是。

基本上,我的问题是,是什么导致了磁盘编号的变化?我错过了什么明显的错误吗?另外,有什么方法可以更好地优化我的代码吗?

另外,这是我正在上的一门课的作业。所以提示和提示将不胜感激。

感谢任何回复的人。

标签: c++recursionconsole

解决方案


推荐阅读