河内迭代解决方案
Hanoi Iterative solution
我正在尝试按照维基百科中的说明在 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;
}
我正在尝试按照维基百科中的说明在 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;
}