河内迭代解决方案

时间:2015-12-13 19:34:54

标签: c++ algorithm iteration

我正试图在维基百科中提到的用c ++实现河内塔迭代解决方案

迭代解决方案的简单陈述

在最小和最小的磁盘之间交替,请按照相应案例的步骤进行操作:

对于偶数个磁盘:

*make the legal move between pegs A and B*
*make the legal move between pegs A and C*
*make the legal move between pegs B and C*
*repeat until complete*

对于奇数个磁盘:

*make the legal move between pegs A and C*
*make the legal move between pegs A and B*
*make the legal move between pegs C and B*
*repeat until complete*

在每种情况下,共进行2n-1次移动。

到目前为止我写的代码是

#include <iostream>
#include <list>    

const int SIZE = 5;
int pCount = 1;
using namespace std;    

list<int> *lhs;
list<int> *mid;
list<int> *rhs;    


void initTower(int size);    

void printPeg(list<int> p);    

bool printTower();    

bool isEven(list<int> l);    

bool move(list<int> *from, list<int> *to);    

int main() {    

    lhs = new list<int>;
    mid = new list<int>;
    rhs = new list<int>;    


    initTower(SIZE);
    printTower();
    bool run = true;
    while (run) {
        int n = SIZE;    

        if (n % 2 == 0) // even
        {
            move(lhs,mid);
            move(lhs,rhs);
            move(mid,rhs);    

        }else{    

            move(lhs,rhs);
            move(lhs,mid);
            move(rhs,mid);    

        }    


        if (rhs->size() == SIZE) {
            run = false;    

        }
    }    


    return 0;
}    


bool isEven(list<int> l) {    

    return l.size() % 2 == 0;    

}    

void initTower(int size) {    

    while (size--)
        lhs->push_back(size + 1);
}    

void printPeg(list<int> p) {    

    if (p.empty()) {
        cout << "empty" << endl;
    } else {
        for (int i: p)
            cout << i << " ";
        cout << endl;
    }    

}    

bool printTower() {    

    cout << "==============" << endl;
    cout << "=====top=======" << pCount++ << endl;
    printPeg(*lhs);
    printPeg(*mid);
    printPeg(*rhs);
    cout << "==============" << endl << endl;    

    return true;    

}    

bool move(list<int> *from, list<int> *to) {
    bool vailidMove = false;
    int fVal = 0;
    int toVal = 0;    

    if (!from->empty())
        fVal = from->back();    

    if (!to->empty())
        toVal = to->back();    


    if ((fVal < toVal || toVal == 0) && (fVal > 0 && fVal != 0)) {
        from->pop_back();
        to->push_back(fVal);
        vailidMove = true;
        printTower();
    }
    return vailidMove;
}    

我对上述程序的输出是。

==============
=====top=======1
5 4 3 2 1 
empty
empty
==============    

==============
=====top=======2
5 4 3 2 
empty
1 
==============    

==============
=====top=======3
5 4 3 
2 
1 
==============    

==============
=====top=======4
5 4 3 
2 1 
empty
==============    

==============
=====top=======5
5 4 
2 1 
3 
==============

我在俯瞰什么?任何建议都有帮助。

1 个答案:

答案 0 :(得分:2)

我在移动函数中添加了一个条件来移动极点fVal > toVal(或者你会停止而不是完成算法)。

我在一半时间内交替了源和目标,正如你所指的wiki文章中所述。 在最小和次最小的磁盘之间交替

我还将pCount初始化更改为0而不是1,因为第一个打印仅列出起始塔并且不是操作。但如果你想要的话,你可以再加1。

PS:我测试了这段代码,它运行得非常好,可以提供2^n-1操作。

#include <iostream>
#include <list>

const int SIZE = 12;
int pCount = 0;
using namespace std;

list<int> *lhs;
list<int> *mid;
list<int> *rhs;


void initTower(int size);

void printPeg(list<int> p);

bool printTower();

bool isEven(list<int> l);

bool move(list<int> *from, list<int> *to);

int main() {

    lhs = new list<int>;
    mid = new list<int>;
    rhs = new list<int>;

    initTower(SIZE);
    printTower();
    bool run = true;
    bool lowest = false;
    while (run) {
        lowest = !lowest;
        int n = SIZE;

        if (n % 2 == 0) // even
        {
            if (lowest){
                move(lhs,mid);
                if (rhs->size() == SIZE) {
                    break;
                }
                move(lhs,rhs);
                move(mid,rhs);
            }else{
                move(mid,lhs);
                if (rhs->size() == SIZE) {
                    break;
                }
                move(rhs,lhs);
                move(rhs,mid);
            }
        }else{
            if (lowest){
                move(lhs,rhs);
                move(lhs,mid);
                if (rhs->size() == SIZE) {
                    break;
                }
                move(mid,rhs);
            }else{
                move(rhs,lhs);
                move(mid,lhs);
                if (rhs->size() == SIZE) {
                    break;
                }
                move(rhs,mid);
            }
        }

        lowest = !lowest;
    }


    return 0;
}


bool isEven(list<int> l) {

    return l.size() % 2 == 0;

}

void initTower(int size) {

    while (size--)
        lhs->push_back(size + 1);
}

void printPeg(list<int> p) {

    if (p.empty()) {
        cout << "empty" << endl;
    } else {
        for (int i: p)
            cout << i << " ";
        cout << endl;
    }

}

bool printTower() {

    cout << "==============" << endl;
    cout << "=====top=======" << pCount++ << endl;
    printPeg(*lhs);
    printPeg(*mid);
    printPeg(*rhs);
    cout << "==============" << endl << endl;

    return true;

}

bool move(list<int> *from, list<int> *to) {
    bool vailidMove = false;
    int fVal = 0;
    int toVal = 0;

    if (!from->empty())
        fVal = from->back();

    if (!to->empty())
        toVal = to->back();

    if ((fVal < toVal || toVal == 0) && fVal > 0) {
        from->pop_back();
        to->push_back(fVal);
        vailidMove = true;
        printTower();
    }else if ((fVal > toVal || fVal == 0) && (toVal > 0 && toVal != 0)) {
        from->push_back(toVal);
        to->pop_back();
        vailidMove = true;
        printTower();
    }
    return vailidMove;
}