Recursion 使用递归的河内塔

Recursion 使用递归的河内塔,recursion,towers-of-hanoi,Recursion,Towers Of Hanoi,我不知道。我想用递归法写一个程序。另一个家庭作业。把你老师的A传给我 资料来源: 奖金:一步一步 关于河内塔 对这一点的分析以及对虚构的神话和四钉版本的讨论可以在《寻找》中找到 河内塔问题有一个很好的递归解 求递归解 要解决这些问题,问问你自己:如果我解决了n-1案例,我能解决n案例吗 如果这个问题的答案是肯定的,那么你就要在n-1案件已经解决的荒谬假设下继续进行。奇怪的是,当n为0或1时,只要有一些基本情况可以作为特例处理,这种方法就行了 如何将n个环从A极移动到C极 如果您知道如何将n-1个

我不知道。我想用递归法写一个程序。

另一个家庭作业。把你老师的A传给我

资料来源: 奖金:一步一步

关于河内塔 对这一点的分析以及对虚构的神话和四钉版本的讨论可以在《寻找》中找到

河内塔问题有一个很好的递归解

求递归解

要解决这些问题,问问你自己:如果我解决了n-1案例,我能解决n案例吗

如果这个问题的答案是肯定的,那么你就要在n-1案件已经解决的荒谬假设下继续进行。奇怪的是,当n为0或1时,只要有一些基本情况可以作为特例处理,这种方法就行了

如何将n个环从A极移动到C极

如果您知道如何将n-1个环从一个极点移动到另一个极点,那么只需将n-1个环移动到备用极点-现在源极点上只剩下一个环,只需将其移动到目标极点,然后将剩余环从备用极点堆积到目标极点

例如,当n为4时

先把三个移动到备用杆上,然后再做

现在将一个环从源极移动到目标极

现在将三个环从备用杆移动到目的杆 同样,我们可以担心以后怎么做

我们完成了

更简洁地说

使用B作为备用,将n个环从A移动到C:

如果n是1 想做就做 否则 将n-1个环从A移动到B,使用C作为备用 将一个环从A移到C 将n-1环从B移动到C,使用A作为备用 与大多数递归解决方案一样,我们必须特别处理一些基本情况——在这里,基本情况发生在只有一个环可以移动的情况下

如何在C中实现它


以下是Lisp中的精简实现:。它当然是递归的,但我没有验证它的正确性。

包含解决此问题的有用提示以及丰富的知识。

来自:

河内塔或河内塔 也被称为梵天之塔 是一个数学游戏或谜题。信息技术 由三根杆和一个数字组成 不同大小的磁盘,可以 滑到任何杆上。谜题开始了 磁盘整齐地堆放在一起 尺寸在一根杆上,最小的在 顶部,从而形成圆锥形

查看。

有关递归算法的描述,请参阅文章

事情是这样的:

#include <iostream>   // ostream
#include <algorithm>  // for_each
#include <deque> // I can iterate over towers & print state,<stack> works as well
#include <boost/array.hpp>   // just a wrapper for array
#include <boost/lambda/lambda.hpp>  // easy one line for_each iterating

using namespace std;

typedef std::deque< int > tower_t;  // stack works as well, deque for printing
typedef boost::array< tower_t ,3 > towers_t;  // 3 towers

enum peg { A = 0, B = 1, C = 2 };
在第一个塔上用4个木桩解决了3个塔,最大的木桩数量最多,最小的是1个

输出mv:PegX从塔-->到塔,然后是移动前后的状态,每个塔从左到右显示从底部到顶部的pegs-顶部位于右侧:

mv: 1 0 --> 1       [4321][][] --> [432][1][]
mv: 2 0 --> 2       [432][1][] --> [43][1][2]
mv: 1 1 --> 2       [43][1][2] --> [43][][21]
mv: 3 0 --> 1       [43][][21] --> [4][3][21]
mv: 1 2 --> 0       [4][3][21] --> [41][3][2]
mv: 2 2 --> 1       [41][3][2] --> [41][32][]
mv: 1 0 --> 1       [41][32][] --> [4][321][]
mv: 4 0 --> 2       [4][321][] --> [][321][4]
mv: 1 1 --> 2       [][321][4] --> [][32][41]
mv: 2 1 --> 0       [][32][41] --> [2][3][41]
mv: 1 2 --> 0       [2][3][41] --> [21][3][4]
mv: 3 1 --> 2       [21][3][4] --> [21][][43]
mv: 1 0 --> 1       [21][][43] --> [2][1][43]
mv: 2 0 --> 2       [2][1][43] --> [][1][432]
mv: 1 1 --> 2       [][1][432] --> [][][4321]

除非你多说,否则这听起来很像一个家庭作业问题。即便如此,这也不是什么问题。你能再说一点吗?你试过什么,哪里有问题?那就去吧!真有趣!我用Pascal完成了那个任务,非常喜欢。。。还是你想让我们帮忙?你应该退房
ostream & show(ostream & os, const tower_t & t)
{
    os << "[";
    for_each (t.begin(), t.end(), os << boost::lambda::_1 );
    return os << "]";
}

ostream & show(ostream & os, const towers_t & t)
{
    show(os, t[0]); show(os, t[1]); show(os, t[2]);
    return os;
}
void move(peg from, peg to, towers_t & t)
{
    // show move and state before move
    cout << "mv: " << t[from].back() << " " << from << " --> " << to << "\t\t";
    show(cout, t); cout << " --> ";

    // the actual move: move top peg `from` stick `to` stick (and `pop` old top)
    t[to].push_back(t[from].back());
    t[from].pop_back();

    // show state after move
    show(cout, t); cout << endl;
}

// move n discs from A to B via C
void move(int n, peg from, peg to, peg via, towers_t & t)
{
    if (n == 1) { move(from, to, t); return; }

    move(n-1, from, via, to, t);
    move(from, to, t);
    move(n-1, via, to, from, t);

    return;
}
int main()
{
    towers_t ttt;
    tower_t & first_tower(ttt[0]);
    first_tower.push_back(4);
    first_tower.push_back(3);
    first_tower.push_back(2);
    first_tower.push_back(1);

    move(first_tower.size(), A, C, B, ttt); // move n from A to C via B
}
mv: 1 0 --> 1       [4321][][] --> [432][1][]
mv: 2 0 --> 2       [432][1][] --> [43][1][2]
mv: 1 1 --> 2       [43][1][2] --> [43][][21]
mv: 3 0 --> 1       [43][][21] --> [4][3][21]
mv: 1 2 --> 0       [4][3][21] --> [41][3][2]
mv: 2 2 --> 1       [41][3][2] --> [41][32][]
mv: 1 0 --> 1       [41][32][] --> [4][321][]
mv: 4 0 --> 2       [4][321][] --> [][321][4]
mv: 1 1 --> 2       [][321][4] --> [][32][41]
mv: 2 1 --> 0       [][32][41] --> [2][3][41]
mv: 1 2 --> 0       [2][3][41] --> [21][3][4]
mv: 3 1 --> 2       [21][3][4] --> [21][][43]
mv: 1 0 --> 1       [21][][43] --> [2][1][43]
mv: 2 0 --> 2       [2][1][43] --> [][1][432]
mv: 1 1 --> 2       [][1][432] --> [][][4321]
#!/usr/bin/env python
discs = 3
T = [range(discs, 0, -1), [], []]

def show_towers():
    """Render a picture of the current state of the towers"""
    def render_disc(t, y):
        return ("-"*(t[y]*2-1) if y < len(t) else "|").center(discs*2)

    for y in range(discs):  
        print " ".join(render_disc(t, discs-y-1) for t in T)
    print "="*(discs*6+3)


def move(n, source, destination):
    """Recursively move n discs from source to destination"""
    while n > 0:
        temp = 3 - source - destination 
        move(n-1, source, temp)
        T[destination].append(T[source].pop())
        show_towers() 
        n, source = n-1, temp    # Simulate tail recursion


show_towers()
move(discs, 0, 2)
  -      |      |   
 ---     |      |   
-----    |      |   
=====================
  |      |      |   
 ---     |      |   
-----    |      -   
=====================
  |      |      |   
  |      |      |   
-----   ---     -   
=====================
  |      |      |   
  |      -      |   
-----   ---     |   
=====================
  |      |      |   
  |      -      |   
  |     ---   ----- 
=====================
  |      |      |   
  |      |      |   
  -     ---   ----- 
=====================
  |      |      |   
  |      |     ---  
  -      |    ----- 
=====================
  |      |      -   
  |      |     ---  
  |      |    ----- 
=====================