Recursive method based on C++ to solve the Tower of Hanoi problem (very detailed)


Look at the problem first


1- The source of the problem

The pastors of Brahma Church encountered a problem. There is a gold plate with 3 diamond needles on it, one of which has 64 gold plates arranged in order of size. When these priests move a plate every day and follow the original order to move these plates to another needle, time will end. Question: If pastors move a plate every day and they start at year 0, when will time end?


2-Problem refinement:

As shown in the figure below, follow the following three rules to move the plate from the left column to the right column:

(1) After a plate is taken away, it must be put back on a certain column;

(2) Once Only one plate can be moved, and it must be the top one on the column;

(3) Large plates cannot be placed on top of small plates.

Insert picture description here


3-Problem analysis

Starting from determining an initial state, this situation is very simple: if there is only one plate, then move from the A column to the C column. When there are n plates, in order to move n plates from A to C, the largest plate n must be moved from A to C, so first move the n-1 plates on it to B It can be solved directly by moving the nth plate on the A column directly to the C column. The remaining problem is to move n-1 plates from the B-pillar to the C-pillar, so solving the Tower of Hanoi problem of order n becomes solving the Tower of Hanoi problem of order n-1, the problem is reduced by one order, you can see that this is A recursive problem. The recursive termination condition is n=1, following the steps of order reduction, n=1 must be reached after a finite step, so that the recursive function can be used to solve this problem.
According to the previous analysis, moving the n plates from the A column to the C column can be broken down into the following 3 steps:

(1) Move the n-1 plates on the top of the A column to the B column, and use the C column to transfer;

(2)

Move the remaining plate on the A-pillar to the C-pillar; (3) Move n–1 plates from the B-pillar to the C-pillar, and use the A-pillar to transfer;

these three steps include two operations:

(1) Moving multiple plates from one column to another is a recursive process.

(2) Move 1 plate from one column to another.


Code example

//汉诺塔游戏
#include <iostream>

using namespace std;
int count=0;
void move(char getone,char putone)
{
    
    	 
	cout<<getone<<"-->"<<putone<<endl;
	count++;
} 
 
 void hanot(int n,char A,char B,char C)
 {
    
    
 	if(n==1)
		move(A,C);
 	else
 	{
    
    
 		hanot(n-1,A,C,B);	//将第n-1个盘从A移动到B 
 		move(A,C);			//将第n个盘从A移动到C 
 		hanot(n-1,B,A,C);	//将第n-1个盘从B移动到C 
	 }
 }
 
 int main()
 {
    
    
 	while(1)
	{
    
    
		int m;
	 	cout<<"输入盘子数:";
		cin>>m;
		cout<<"移动"<<m<<"个盘的步骤为:"<<endl;
		hanot(m,'A','B','C');
		cout<<"总共移动的步数为"<<count<<"次"<<endl;
		cout<<"------------------------------"<<endl;
	}	
	return 0; 
 }

Its operating effects are as follows

Insert picture description here
The main part of the program is that you
Insert picture description here
might as well take n=2 into it, you can easily understand the program,
Insert picture description here

but when I take n to 3 or greater, the steps performed by the program will become very large, and the recursion starts to emit Great magic power, successfully made me dizzy. When I wrote the program execution steps on the draft paper until I gave up, I suddenly made an alarm and decided to print out all the program execution steps, as follows:

Insert picture description here
The code is as follows:

//汉诺塔游戏
#include <iostream>
#include <windows.h>
#include <string.h>
using namespace std;

//设置在控制台打印的字体的颜色,可选white,red,green,blue,yellow,magenta,cyan 
void textcolor(char *color)
{
    
    
	if(!strcmp(color,"white")) SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
	else if(!strcmp(color,"red")) SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY | FOREGROUND_RED);
	else if(!strcmp(color,"green")) SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY | FOREGROUND_GREEN);
	else if(!strcmp(color,"blue")) SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY | FOREGROUND_BLUE);
	else if(!strcmp(color,"yellow")) SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN);
	else if(!strcmp(color,"magenta")) SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_BLUE);
	else if(!strcmp(color,"cyan")) SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_BLUE);
}

void move(char getone,char putone)
{
    
    	 
	textcolor("red");
	cout<<getone<<"-->"<<putone<<endl;		//在控制台打印出移动步骤为红色 
	textcolor("cyan");
 } 
 
 void hanot(int n,char A,char B,char C)
 {
    
    
 	cout<<"if("<<n<<"==1)"<<endl;
 	if(n==1)
 	{
    
    
 		cout<<"move("<<A<<","<<C<<");"<<endl;
		move(A,C);
	}
 	else
 	{
    
    
 		cout<<"hanot("<<n-1<<","<<A<<","<<C<<","<<B<<");"<<endl;
 		hanot(n-1,A,C,B);	//将第n-1个盘从A移动到B 
 		cout<<"move("<<A<<","<<C<<");"<<endl;
 		move(A,C);			//将第n个盘从A移动到C 
 		cout<<"hanot("<<n-1<<","<<B<<","<<A<<","<<C<<");"<<endl;
 		hanot(n-1,B,A,C);	//将第n-1个盘从B移动到C 
	 }
 }
 
 int main()
 {
    
    
 	while(1)
	{
    
    
		int m;
		textcolor("white");
	 	cout<<"输入盘子数:";
		cin>>m;
		cout<<"移动"<<m<<"个盘的步骤为红色,程序的执行步骤为青色:"<<endl;
		textcolor("cyan");
		hanot(m,'A','B','C');
		cout<<"------------------------------"<<endl;
	}	
	return 0; 
 }

Looking at the main part of the function again, is the program execution step clear?
Insert picture description here

Guess you like

Origin blog.csdn.net/weixin_46977029/article/details/109252971