C++ 河內之塔
我正在做一本书中的练习,这本书要求我们使用递归方法解决河内塔问题。我找到了一个解决方案,但从我浏览完互联网后收集到的信息来看,我的解决方案可能不正确。有人知道更好/不同的解决问题的方法吗?有人对改进有什么建议吗。(顺便说一句,输出是正确的。它只应该告诉从哪个塔到另一个塔的销钉正在移动,而不是具体告诉哪些销钉) 代码如下:C++ 河內之塔,c++,recursion,towers-of-hanoi,C++,Recursion,Towers Of Hanoi,我正在做一本书中的练习,这本书要求我们使用递归方法解决河内塔问题。我找到了一个解决方案,但从我浏览完互联网后收集到的信息来看,我的解决方案可能不正确。有人知道更好/不同的解决问题的方法吗?有人对改进有什么建议吗。(顺便说一句,输出是正确的。它只应该告诉从哪个塔到另一个塔的销钉正在移动,而不是具体告诉哪些销钉) 代码如下: #include <iostream> #include <cmath> using namespace std; static int count
#include <iostream>
#include <cmath>
using namespace std;
static int counter = 0;
void ToH(int dskToMv, int cLocation, int tmpLocation, int fLocation)
{
if (dskToMv == 0);
else
{
if (dskToMv%2!=0)
{
cout << cLocation << "->" << tmpLocation << endl;
cout << cLocation << "->" << fLocation << endl;
cout << tmpLocation << "->" << fLocation << endl;
ToH(dskToMv-1, cLocation, fLocation, tmpLocation);
}
else if (dskToMv%2==0)
{
counter++;
if (counter%2==0)
cout << fLocation << "->" << cLocation << endl;
else
cout << cLocation << "->" << fLocation << endl;
ToH(dskToMv-1, tmpLocation, cLocation, fLocation);
}
}
}
int main()
{
int x, j;
cout << "Enter number of disks: ";
cin >> x;
j = pow(2.0, x-1)-1;
if (x%2==0)
ToH(j, 1, 2, 3);
else
ToH(j, 1, 3, 2);
return 0;
}
#包括
#包括
使用名称空间std;
静态整数计数器=0;
无效ToH(内部dskToMv、内部CLOCION、内部TMPLOCION、内部FLOCION)
{
如果(dskToMv==0);
其他的
{
如果(dskToMv%2!=0)
{
cout回答你的问题:是的,这被限定为递归。任何时候函数调用自己,它都是递归
话虽如此,您的代码可以大幅缩减:
#include <iostream>
using namespace std;
void ToH(int dskToMv, int cLocation, int tmpLocation, int fLocation)
{
if( dskToMv != 0 )
{
ToH( dskToMv-1, cLocation, fLocation, tmpLocation );
cout << cLocation << "->" << fLocation << endl;
ToH( dskToMv-1, tmpLocation, cLocation, fLocation );
}
}
int main()
{
int x;
cout << "Enter number of disks: ";
cin >> x;
ToH(x, 1, 2, 3);
return 0;
}
#包括
使用名称空间std;
无效ToH(内部dskToMv、内部CLOCION、内部TMPLOCION、内部FLOCION)
{
如果(dskToMv!=0)
{
ToH(dskToMv-1,封闭,絮凝,TMPLOCION);
cout如果你递归地看问题,这是最简单的:
要将N张光盘从A移动到B(使用C):
如果(N>1)将N-1张光盘从A移动到C(使用B)
将一张光盘从A移到B
如果(N>1)将N-1张光盘从C移动到B(使用A)
对于任何给定的调用,无论哪一个peg不是源还是目标都是辅助的
回答您的实际问题:是的,您的解决方案似乎是递归的,尽管比实际需要的要复杂一些。每个递归方法都有3个步骤
1) 检查条件
2) 满足检查条件时返回值。
3) 对方法本身的调用
@Stargazer712解决方案是完美的。#包括
#include <iostream>
using namespace std;
void towers(int, char, char, char);
void towers(int num, char frompeg, char topeg, char auxpeg)
{
if (num == 1)
{
cout<<"\n Move disk 1 from peg "<<frompeg<<" to peg "<<topeg<<endl;
return;
}
towers(num - 1, frompeg, auxpeg, topeg);
cout<<"\n Move disk "<<num<<" from peg "<<frompeg<<" to peg " <<topeg<<endl;
towers(num - 1, auxpeg, topeg, frompeg);
}
int main()
{
int num;
cout<<"Enter the number of disks : ";
cin>>num;
cout<<"The sequence of moves involved in the Tower of Hanoi are :\n"<<endl;
towers(num, 'A', 'C', 'B');
return 0;
}
使用名称空间std;
空塔(int,char,char,char);
空塔(int-num、char-frompeg、char-topeg、char-auxpeg)
{
如果(num==1)
{
cout这里是河内塔的递归解
#include <iostream>
#include <string>
#include <algorithm>
#include <vector>
using namespace std;
void move(vector<int>& frompeg, vector<int>& topeg) {
topeg.push_back(frompeg.back());
frompeg.pop_back();
}
void hanoi(vector<int>& frompeg, vector<int>& topeg, vector<int>& auxpeg,
int num_disks) {
if (num_disks == 1) {
move(frompeg, topeg);
}
else {
hanoi(frompeg, auxpeg, topeg, num_disks - 1);
move(frompeg, topeg);
hanoi(auxpeg, topeg, frompeg, num_disks - 1);
}
}
void printpeg(vector<int> a, vector<int> b, vector<int> c) {
cout << "a: ";
for (int i = 0; i < a.size(); i++) {
cout << a[i] << " ";
}
cout << "\n";
cout << "b: ";
for (int i = 0; i < b.size(); i++) {
cout << b[i] << " ";
}
cout << "\n";
cout << "c: ";
for (int i = 0; i < c.size(); i++) {
cout << c[i] << " ";
}
}
int main() {
int n;
cin >> n;
vector<int> a,b,c;
for (int i = 0; i < n; i++) {
a.push_back(n - i);
}
cout << "befor: " << endl;
printpeg(a, b, c);
hanoi(a, b, c, n);
cout << "after: " << endl;
printpeg(a, b, c);
cin.get();
cin.get();
return 0;
}
#包括
#包括
#包括
#包括
使用名称空间std;
无效移动(向量和frompeg、向量和topeg){
顶推(从peg.back()向后推);
frompeg.pop_back();
}
void hanoi(向量和frompeg、向量和topeg、向量和auxpeg、,
int num_磁盘){
if(num_disks==1){
移动(从PEG、topeg);
}
否则{
河内(frompeg、auxpeg、topeg、num_磁盘-1);
移动(从PEG、topeg);
河内(auxpeg、topeg、frompeg、num_disks-1);
}
}
void printpeg(向量a、向量b、向量c){
噢,谢谢!我觉得我的代码有点笨拙,但我不知道它可以被修剪那么多!:Dsidenote:从这一点,你也可以很快得到所需的步骤数:H(n)=2*H(n-1)+1
。现在如果你把两边都加上1,你会得到一个很好的H(n)+1=2(H(n-1)+1)
递归方程,因为H(1)=1
您得到了H(n)=2^n-1
@Stargazer正在处理它!现在您发布了答案,这看起来很明显。再次感谢!只是为了挑剔,递归必须有一个定义的结束情况,而不仅仅是一个函数调用本身。在这段代码中,它是:if(dskToMv!=0)< /代码>。无论哪种方式,代码仍然是递归的。@ Robert Gowland,对于形成良好的递归来说,一个终结点是必要的,但是无限递归仍然被认为是递归的一种类型吗?- P.并不重要):对于河内塔难题的变体,请检查这本书:具体的数学——计算机科学的基础。我使用函数。这就是所谓的递归函数,在这段代码中,函数一次又一次地调用自己……这就是整个程序的运行方式,而这段代码可能会回答这个问题,提供关于为什么和/或这段代码回答这个问题的额外上下文,从而提高它的长期价值。