用堆栈实现汉诺塔。
初版代码:只能移动,不判断盘片大小,字符控制盘片移动。
// hanno.c
#include <iostream>
class FDSTACK{
/*
stack栈 按照后进先出LIFO规则运行。
堆栈的基本操作:
初始化
测试是否已满
进栈
出栈
检查栈顶元素
*/
/*
1.构造顺序堆栈
*/
#define EMPTY 0
#define FULL 1
#define PASS 2
#define FAIL 3
private:
int *stack;
int topStack;
int maxBuffer;
public:
FDSTACK(int bufferLength){ // 栈初始化
stack = new int[bufferLength];
this->maxBuffer = bufferLength;
}
~FDSTACK(){
free(stack);
}
void traversal(){ // 遍历堆栈数据
for(int i = 0; i <= topStack; i++){
std::cout << stack[i] << " ";
}
std::cout << std::endl;
}
int getBufferLength(){ // 获取堆栈长度
return this->maxBuffer;
}
int getCount(){ // 读取栈中元素个数
return this->topStack + 1;
}
void initialStack(){ // 初始化堆栈
topStack = -1;
}
int isEmpty(){ // 测试堆栈是否为空,为空返回0
return topStack == -1;
}
int isFull(){ // 测试堆栈是否已满,为满返回1
return topStack == (getBufferLength() - 1);
}
int pushStack(int data){ // 入栈 成功返回PASS,失败返回FAIL
if(isFull()){
return FAIL;
}else{
stack[++topStack] = data;
}
return PASS;
}
int popStack(){ // 出栈 成功返回数据
if(isEmpty()){
return FAIL;
}else{
return stack[topStack--];
}
}
int getTop(){ // 读取栈顶元素
if(isEmpty()){
return FAIL;
}else{
return stack[topStack];
}
}
};
void disp(FDSTACK *st){
}
int main(){
FDSTACK s[3] = {3,3,3};
s[0].initialStack();
s[1].initialStack();
s[2].initialStack();
/*
l 光标左移
r 光标右移
s 选中
p 放置
*/
char ctrlCode[] = "srrpllsrprslplsrrplslprsrpllsrrp";
int temp = 0;
int select = 0;
for(int i = 3; i > 0; --i){ // hanno initial, 3block
s[0].pushStack(i);
}
for(int i = 0;i < sizeof(ctrlCode); i++){
switch(ctrlCode[i]){
case 'l':
select -= 1;
if(select < 0){
select = 0;
}
break;
case 'r':
select += 1;
if(select > 3){
select = 3;
}
break;
case 's':
temp = s[select].popStack();
break;
case 'p':
s[select].pushStack(temp);
break;
}
}
s[0].traversal();
s[1].traversal();
s[2].traversal();
std::cout << "----------" << std::endl;
return 0;
}
修改后的代码,添加插入检测功能,
对于三级汉诺塔,参考下面的操作指令序列:
char ctrlCode[] = "srrpllsrprslplsrrplslprsrpllsrrp"; // 移动所有盘子到右边。
char ctrlCode[] = " srrpllsrrp"; // 一个错误的操作
错误操作的输出,遇到非法操作时出现“error”提示,不做任何移动操作:
3 2 1
play count: 0
select: 0
cur: 0
----------
3 2
play count: 1
select: 1
cur: 0
----------
3 2
play count: 2
select: 1
cur: 1
----------
3 2
play count: 3
select: 1
cur: 2
----------
3 2
1
play count: 4
select: 1
cur: 2
----------
3 2
1
play count: 5
select: 1
cur: 1
----------
3 2
1
play count: 6
select: 1
cur: 0
----------
3
1
play count: 7
select: 2
cur: 0
----------
3
1
play count: 8
select: 2
cur: 1
----------
3
1
play count: 9
select: 2
cur: 2
----------
error
3
1
play count: 10
select: 2
cur: 2
----------
移动所有盘子到右边的输出,步骤略长:
3 2
play count: 0
select: 1
cur: 0
----------
3 2
play count: 1
select: 1
cur: 1
----------
3 2
play count: 2
select: 1
cur: 2
----------
3 2
1
play count: 3
select: 1
cur: 2
----------
3 2
1
play count: 4
select: 1
cur: 1
----------
3 2
1
play count: 5
select: 1
cur: 0
----------
3
1
play count: 6
select: 2
cur: 0
----------
3
1
play count: 7
select: 2
cur: 1
----------
3
2
1
play count: 8
select: 2
cur: 1
----------
3
2
1
play count: 9
select: 2
cur: 2
----------
3
2
play count: 10
select: 1
cur: 2
----------
3
2
play count: 11
select: 1
cur: 1
----------
3
2 1
play count: 12
select: 1
cur: 1
----------
3
2 1
play count: 13
select: 1
cur: 0
----------
2 1
play count: 14
select: 3
cur: 0
----------
2 1
play count: 15
select: 3
cur: 1
----------
2 1
play count: 16
select: 3
cur: 2
----------
2 1
3
play count: 17
select: 3
cur: 2
----------
2 1
3
play count: 18
select: 3
cur: 1
----------
2
3
play count: 19
select: 1
cur: 1
----------
2
3
play count: 20
select: 1
cur: 0
----------
1
2
3
play count: 21
select: 1
cur: 0
----------
1
2
3
play count: 22
select: 1
cur: 1
----------
1
3
play count: 23
select: 2
cur: 1
----------
1
3
play count: 24
select: 2
cur: 2
----------
1
3 2
play count: 25
select: 2
cur: 2
----------
1
3 2
play count: 26
select: 2
cur: 1
----------
1
3 2
play count: 27
select: 2
cur: 0
----------
3 2
play count: 28
select: 1
cur: 0
----------
3 2
play count: 29
select: 1
cur: 1
----------
3 2
play count: 30
select: 1
cur: 2
----------
3 2 1
play count: 31
select: 1
cur: 2
----------
3 2 1
play count: 32
select: 1
cur: 2
----------
最后的代码:
// hanno.c
#include <iostream>
class FDSTACK{
/*
stack栈 按照后进先出LIFO规则运行。
堆栈的基本操作:
初始化
测试是否已满
进栈
出栈
检查栈顶元素
*/
/*
1.构造顺序堆栈
*/
#define EMPTY 0
#define FULL 1
#define PASS 2
#define FAIL 3
private:
int *stack;
int topStack;
int maxBuffer;
public:
FDSTACK(int bufferLength){ // 栈初始化
stack = new int[bufferLength];
this->maxBuffer = bufferLength;
}
~FDSTACK(){
free(stack);
}
void traversal(){ // 遍历堆栈数据
for(int i = 0; i <= topStack; i++){
std::cout << stack[i] << " ";
}
std::cout << std::endl;
}
int getBufferLength(){ // 获取堆栈长度
return this->maxBuffer;
}
int getCount(){ // 读取栈中元素个数
return this->topStack + 1;
}
void initialStack(){ // 初始化堆栈
topStack = -1;
}
int isEmpty(){ // 测试堆栈是否为空,为空返回0
return topStack == -1;
}
int isFull(){ // 测试堆栈是否已满,为满返回1
return topStack == (getBufferLength() - 1);
}
int pushStack(int data){ // 入栈 成功返回PASS,失败返回FAIL
if(isFull()){
return FAIL;
}else{
stack[++topStack] = data;
}
return PASS;
}
int popStack(){ // 出栈 成功返回数据
if(isEmpty()){
return FAIL;
}else{
return stack[topStack--];
}
}
int getTop(){ // 读取栈顶元素
if(isEmpty()){
return FAIL;
}else{
return stack[topStack];
}
}
};
void disp(FDSTACK *st){
}
int main(){
FDSTACK s[3] = {3,3,3};
s[0].initialStack();
s[1].initialStack();
s[2].initialStack();
/*
l 光标左移
r 光标右移
s 选中
p 放置
*/
// char ctrlCode[] = "srrpllsrprslplsrrplslprsrpllsrrp";
char ctrlCode[] = " srrpllsrrp";
int temp = 0;
int select = 0;
int playCount = 0;
for(int i = 3; i > 0; --i){ // hanno initial, 3block
s[0].pushStack(i);
}
for(int i = 0;i < sizeof(ctrlCode); i++){
switch(ctrlCode[i]){
case 'l':
select -= 1;
if(select < 0){
select = 0;
}
break;
case 'r':
select += 1;
if(select > 3){
select = 3;
}
break;
case 's':
temp = s[select].popStack();
break;
case 'p':
if(s[select].isEmpty()){
s[select].pushStack(temp);
}else{
if(temp > s[select].getTop()){
std::cout << "error" << std::endl;
continue;
}else{
s[select].pushStack(temp);
}
}
break;
}
s[0].traversal();
s[1].traversal();
s[2].traversal();
std::cout << "play count: " << playCount << std::endl;
std::cout << "select: " << temp << std::endl;
std::cout << "cur: " << select << std::endl;
std::cout << "----------" << std::endl;
playCount++;
}
return 0;
}