河内的塔

时间:2011-07-18 21:00:19

标签: c++ recursion towers-of-hanoi

我正在书中练习,要求我们使用递归方法解决河内塔问题。我已经找到了解决方案,但是在完成浏览互联网后我收集的内容是我的解决方案可能不正确。有谁知道更好/不同的方法来解决问题?有没有人有任何改进的建议。 (顺便说一句,输出是正确的。它只能告诉从哪个塔到另一个桩移动,而不是具体是哪个钉)

以下是代码:

#include <iostream>
#include <cmath>

using namespace std;

static int counter = 0;

void ToH(int dskToMv, int cLocation, int tmpLocation, int fLocation)
{
if (dskToMv == 0);
else
{
    if (dskToMv%2!=0)
    {
        cout << cLocation << "->" << tmpLocation << endl;
        cout << cLocation << "->" << fLocation << endl;
        cout << tmpLocation << "->" << fLocation << endl;
        ToH(dskToMv-1, cLocation, fLocation, tmpLocation);
    }
    else if (dskToMv%2==0)
    {
        counter++;
        if (counter%2==0)
            cout << fLocation << "->" << cLocation << endl;
        else
            cout << cLocation << "->" << fLocation << endl;
        ToH(dskToMv-1, tmpLocation, cLocation, fLocation);
    }
}
}

int main()
{
int x, j;
cout << "Enter number of disks: ";
cin >> x;
j = pow(2.0, x-1)-1;
if (x%2==0)
    ToH(j, 1, 2, 3);
else
    ToH(j, 1, 3, 2);
return 0;
}

此方法是否合格为递归?

5 个答案:

答案 0 :(得分:6)

回答你的问题:是的,这是合格的递归。只要函数调用自身,它就是递归。

话虽如此,您的代码可以大幅削减:

#include <iostream>

using namespace std;

void ToH(int dskToMv, int cLocation, int tmpLocation, int fLocation)
{
    if( dskToMv != 0 ) 
    {
        ToH( dskToMv-1, cLocation, fLocation, tmpLocation );
        cout << cLocation << "->" << fLocation << endl;
        ToH( dskToMv-1, tmpLocation, cLocation, fLocation );
    }
}

int main()
{
    int x;
    cout << "Enter number of disks: ";
    cin >> x;
    ToH(x, 1, 2, 3);
    return 0;
}

答案 1 :(得分:0)

如果你以递归方式查看问题,这是最简单的:

将N张光盘从A移动到B(使用C):

  1. if(N> 1)将N-1个盘从A移动到C(使用B)
  2. 将一张光盘从A移动到B
  3. if(N> 1)将N-1个盘从C移动到B(使用A)
  4. 对于任何给定的电话,无论哪个挂钩,源或目的地都是附属的。

    回答你的实际问题:是的,你的解决方案似乎是递归的,虽然比实际需要的要复杂得多。

答案 2 :(得分:0)

每个递归方法都有3个步骤

1)检查条件 2)满足检查条件时的返回值。 3)对方法本身的调用

@ Stargazer712解决方案非常完美。

答案 3 :(得分:0)

#include <iostream>

using namespace std;

void towers(int, char, char, char);

void towers(int num, char frompeg, char topeg, char auxpeg)
{
    if (num == 1)
    {

        cout<<"\n Move disk 1 from peg "<<frompeg<<" to peg "<<topeg<<endl;

        return;
    }

    towers(num - 1, frompeg, auxpeg, topeg);

    cout<<"\n Move disk "<<num<<" from peg "<<frompeg<<" to peg "   <<topeg<<endl;

    towers(num - 1, auxpeg, topeg, frompeg);
}

int main()
{
    int num;

    cout<<"Enter the number of disks : ";

    cin>>num;

    cout<<"The sequence of moves involved in the Tower of Hanoi are :\n"<<endl;

    towers(num, 'A', 'C', 'B');

    return 0;
}

答案 4 :(得分:0)

这是河内塔的递归解决方案。

#include <iostream>
#include <string>
#include <algorithm>
#include <vector>

using namespace std;

void move(vector<int>& frompeg, vector<int>& topeg) {
    topeg.push_back(frompeg.back());
    frompeg.pop_back();
}

void hanoi(vector<int>& frompeg, vector<int>& topeg, vector<int>& auxpeg, 
int num_disks) {
    if (num_disks == 1) {
        move(frompeg, topeg);
    }
    else {
        hanoi(frompeg, auxpeg, topeg, num_disks - 1);
        move(frompeg, topeg);
        hanoi(auxpeg, topeg, frompeg, num_disks - 1);
    }
}

void printpeg(vector<int> a, vector<int> b, vector<int> c) {
    cout << "a: ";
    for (int i = 0; i < a.size(); i++) {
        cout << a[i] << " ";
    }
    cout << "\n";
    cout << "b: ";
    for (int i = 0; i < b.size(); i++) {
        cout << b[i] << " ";
    }
    cout << "\n";
    cout << "c: ";
    for (int i = 0; i < c.size(); i++) {
        cout << c[i] << " ";
    }

}

int main() {

    int n;
    cin >> n;
    vector<int> a,b,c;
    for (int i = 0; i < n; i++) {
        a.push_back(n - i);
    }
    cout << "befor: " << endl;
    printpeg(a, b, c);
    hanoi(a, b, c, n);
    cout << "after: " << endl;
    printpeg(a, b, c);
    cin.get();
    cin.get();
    return 0;
    }