Hanoi迭代解决方案
Hanoi Iterative solution
如Wikepedia 中所述,我正试图在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
==============
我在俯瞰什么?任何建议都是有用的。
如果fVal > toVal
,我在移动函数中添加了一个条件来移动极点(或者你会停止而不是完成算法)。
我有一半的时间交替使用源和目的地,正如你提到的维基文章中所说的那样。在最小磁盘和次最小磁盘之间交替
我还将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;
}
相关文章:
- 使用std::multimap迭代器创建std::list
- 来自 std::list 的迭代器 .end() 按预期返回"0xcdcdcdcdcdcdcdcd"但 .begin()
- 运行同一解决方案的另一个项目的项目
- Project Euler问题4的错误解决方案
- 如何解决我们必须向前和向后迭代的项链断裂问题
- 将多个非原始递归调用转换为迭代解决方案
- 是否有一个很好的方法可以在C 11中打印出像JSON一样的Trie结构(仅迭代解决方案)的扁平命名空间
- 我正在写一个快速的形式,可以跟踪迭代次数.但是,计数每次返回0.我怎样才能解决这个问题
- 如果使用迭代器,如何解决遍历列表的问题
- 具有C 的迭代解决方案
- 迭代解决方案作为动态编程
- C++迭代时删除列表成员:标准解决方案不起作用
- 将递归解决方案转换为迭代解决方案
- 为什么第二次迭代大量字节的速度要慢得多?以及如何解决它
- 如何在Barrier算法迭代后访问当前解决方案
- Hanoi迭代解决方案
- 如何将递归解决方案转换为迭代解决方案
- 比迭代所有组合更简单的解决方案
- 如何解决一系列关于迭代器构造函数的错误,包括期望的左值、缺失的转换和可行性
- 如何在c++11中将迭代器转换为字符串?boost解决方案也可以