简体   繁体   中英

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

The Towers of Hanoi is very interesting and hard problem, which I assume we all know, but if someone does not here it is:

Towers of Hanoi problem

I have been searching and trying to implement a complete C++ solution, where by "complete" I mean that for a given number of disks the program calculates the steps needed and prints out every step and current state of every rod. Where the rods are represented as stacks.

For example let's take 3 disks. The output in this case must be:

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
----------------------------

I'm having a very BIG trouble and headache when I try to do that with C++. I start with making the stacks hardcoded just to test the problem and attain the following:

#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;
}

which works just fine, BUT when I try to make the stacks not hard coded the result collapses. It gives wrong result like:

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
----------------------------

or even worse when I try to fix it more deeply.

Can someone PLEASE help me how to move the stacks inside the main function?

When recursion occurs the "src", "dest" and "spare" references are swapped, so if you pass those references to the PrintRods() function it will output the stacks in the wrong order.

To get around this you could have an additional set of references to the stacks as parameters to the MoveDisks() function.

Try this (it is not pretty but it works):

#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;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM