我怎样才能制作硬编码堆栈,而不是硬编码并正确保存程序 运行

How can I make hardcoded stacks, not hardcoded and keep the program running properly

河内塔是一个非常有趣和困难的问题,我想我们都知道,但如果有人不知道这里是:

Towers of Hanoi problem

我一直在搜索并尝试实现一个完整的 C++ 解决方案,其中 "complete" 我的意思是对于给定数量的磁盘,程序计算所需的步骤并打印出每个步骤和每个磁盘的当前状态竿。其中杆表示为堆叠。

例如让我们拿3个磁盘。这种情况下的输出必须是:

Enter number of disks: 3
Source: 3, 2, 1
Destination: empty rod
Spare: empty rod
----------------------------
Step #1: Moved disk 1
Source: 3, 2
Destination: 1
Spare: empty rod
----------------------------
Step #2: Moved disk 2
Source: 3
Destination: 1
Spare: 2
----------------------------
Step #3: Moved disk 1
Source: 3
Destination: empty rod
Spare: 2, 1
----------------------------
Step #4: Moved disk 3
Source: empty rod
Destination: 3
Spare: 2, 1
----------------------------
Step #5: Moved disk 1
Source: 1
Destination: 3
Spare: 2
----------------------------
Step #6: Moved disk 2
Source: 1
Destination: 3, 2
Spare: empty rod
----------------------------
Step #7: Moved disk 1
Source: empty rod
Destination: 3, 2, 1
Spare: empty rod
----------------------------

当我尝试使用 C++ 执行此操作时,我遇到了非常大的麻烦和头痛。我开始对堆栈进行硬编码只是为了测试问题并实现以下目标:

#include <iostream>
#include <stack>

std::stack<int> src;
std::stack<int> dest;
std::stack<int> spare;

int setTowers()
{
    int disks;
    std::cout << "Enter number of disks: ";
    std::cin >> disks;

    for (int i = 0; i < disks; i++) src.push(disks - i);
    return disks;
}

void printRod(std::stack<int>tower)
{
    std::stack<int>temp;
    while (!tower.empty())
    {
        temp.push(tower.top());
        tower.pop();
    }
    if (!temp.size()) std::cout << "empty rod\n";
    else
    {
        while (!temp.empty())
        {
            std::cout << temp.top();
            temp.pop();
            if (temp.size() != 0) std::cout << ", ";
        }
        std::cout << '\n';
    }
}

void PrintRods()
{
    std::cout << "Source: "; printRod(src);
    std::cout << "Destination: ", printRod(dest);
    std::cout << "Spare: ", printRod(spare);
    std::cout << "----------------------------\n";
}

void MoveDisks(int disks, std::stack<int>& src, std::stack<int>& dest, std::stack<int>& spare,unsigned& stepsTaken)
{
    if (disks < 1)  return; 
    else if (disks == 1)
    {
        stepsTaken++;
        dest.push(src.top());
        src.pop();
        std::cout << "Step #" << stepsTaken << ": Moved disk " << disks << '\n';
        PrintRods();
        return;
    }
    else
    {
        MoveDisks(disks - 1, src, spare, dest, stepsTaken);
        stepsTaken++;
        dest.push(src.top());
        src.pop();
        std::cout << "Step #" << stepsTaken << ": Moved disk " << disks << '\n';
        PrintRods();
        MoveDisks(disks - 1, spare, dest, src, stepsTaken);
    }
}
int main()
{
    unsigned stepsTaken(0);
    int disks = setTowers();
    PrintRods();
    MoveDisks(disks, src, dest, spare, stepsTaken);
    return 0;
}

效果很好,但是当我尝试使堆栈不硬编码时,结果崩溃了。它给出了错误的结果,如:

Enter number of disks: 3
Source: 3, 2, 1
Destination: empty rod
Spare: empty rod
----------------------------
Step #1: Moved disk 1
Source: 3, 2
Destination: 1
Spare: empty rod
----------------------------
Step #2: Moved disk 2
Source: 3
Destination: 1
Spare: 2
----------------------------
Step #3: Moved disk 1
Source: empty rod
Destination: 2, 1
Spare: 3
----------------------------
Step #4: Moved disk 3
Source: empty rod
Destination: 2, 1
Spare: 3
----------------------------
Step #5: Moved disk 1
Source: 2
Destination: 1
Spare: 3
----------------------------
Step #6: Moved disk 2
Source: empty rod
Destination: 1
Spare: 3, 2
----------------------------
Step #7: Moved disk 1
Source: empty rod
Destination: 3, 2, 1
Spare: empty rod
----------------------------

当我尝试更深入地修复它时甚至更糟。

有人可以帮我如何在 main 函数中移动堆栈吗?

当递归发生时,"src"、"dest" 和 "spare" 引用被交换,因此如果您将这些引用传递给 PrintRods() 函数,它将以错误的方式输出堆栈订单。

为了解决这个问题,您可以将一组额外的堆栈引用作为 MoveDisks() 函数的参数。

试试这个(它不漂亮但很管用):

#include<iostream>
#include<stack>
using namespace std;
int setTowers(std::stack<int>& src)
{
    int disks;
    std::cout << "Enter number of disks: ";
    std::cin >> disks;

    for (int i = 0; i < disks; i++) src.push(disks - i);
    return disks;
}

void printRod(std::stack<int>tower)
{
    std::stack<int>temp;
    while (!tower.empty())
    {
        temp.push(tower.top());
        tower.pop();
    }
    if (!temp.size()) std::cout << "empty rod\n";
    else
    {
        while (!temp.empty())
        {
            std::cout << temp.top();
            temp.pop();
            if (temp.size() != 0) std::cout << ", ";
        }
        std::cout << '\n';
    }
}

void PrintRods(std::stack<int>& src, std::stack<int>& dest, std::stack<int>& spare)
{
    std::cout << "Source: "; printRod(src);
    std::cout << "Destination: ", printRod(dest);
    std::cout << "Spare: ", printRod(spare);
    std::cout << "----------------------------\n";
}

void MoveDisks(int disks, std::stack<int>& src, std::stack<int>& dest, std::stack<int>& spare,std::stack<int>&a,std::stack<int>&b,std::stack<int>&c,unsigned& stepsTaken)
{
    if (disks < 1)  return;
    else if (disks == 1)
    {
        stepsTaken++;
        dest.push(src.top());
        src.pop();
        std::cout << "Step #" << stepsTaken << ": Moved disk " << disks << '\n';
        PrintRods(a,b,c);
        return;
    }
    else
    {
        MoveDisks(disks - 1, src, spare, dest,a,b,c,stepsTaken);
        stepsTaken++;
        dest.push(src.top());
        src.pop();
        std::cout << "Step #" << stepsTaken << ": Moved disk " << disks << '\n';
        PrintRods(a,b,c);
        MoveDisks(disks - 1, spare, dest, src, a,b,c,stepsTaken);
    }
}
int main()
{
    std::stack<int> src;
    std::stack<int> dest;
    std::stack<int> spare;

    unsigned stepsTaken(0);
    int disks = setTowers(src);
    PrintRods(src, dest, spare);
    MoveDisks(disks, src, dest, spare,src,dest,spare,stepsTaken);
    return 0;
}