在学习递归的时候试着写了一下汉诺塔,但是把递归逻辑变成代码的过程似乎有问题。我的思路是:
根据递归逻辑,重复的内容是:哪个盘子,从哪个柱子,移动到哪个柱子,所以需要的参数是:盘子的数量、盘子现在所在柱子的编号、盘子要放到的柱子的编号,所以函数定义为move(int n, char from, char to)
,测试调用时from的值为'A',to的值为'C'
对函数分类讨论,如果n=1,则syso(n+"从"+from+"到"+to)
来代表第一个盘子的移动;如果n>1,则执行以下三步:
n-1个盘子从A到B:move(n, 'A', 'B')
第n个盘子从A到C:syso(n+"从A到C")
n-1个盘子从B到C:move(n, 'B', 'C')
完整的代码如下:
package algorithm;
import java.util.Scanner;
public class Hannuo {
void play(int n, char from, char to) {
if(n==1)
System.out.println("["+n+"]:"+from+">>>>"+to);
else {
this.play(n-1, 'A', 'B');
System.out.println("["+n+"]:A>>>>C");
this.play(n-1, 'B', 'C');
}
}
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
Hannuo h = new Hannuo();
while(true) {
System.out.println("请输入盘数:");
int n=sc.nextInt();
if(n==0)
break;
h.play(n, 'A', 'C');
}
sc.close();
}
}
但是n=3的情况下的执行结果就不对,我去网上查了以下其他人的,函数都是定义了4个输入参数,多了一个“过渡柱子”的参数,但是根据递归逻辑,移动的过程就是哪个盘子、从哪个柱子、到哪个柱子,没有提到第三个柱子,所以想不明白为什么正确的代码有第三个柱子作为参数,以及为什么我自己设计的代码逻辑错在哪个地方,希望能帮忙指导一下
既然你要用递归的思想,那么你就要先明白递归的思想到底和循环差在哪里
先说循环,循环是个正向的逻辑,你必须首先知道第1步要干什么,然后你要知道第k+1步比第k步多做了什么,然后代入,开始迭代,从1迭代到n
而递归是反向的逻辑
一开始并不管第一步要干什么,只关心从第k-1步到第k步到底怎么实现,然后往回倒,一直倒到有一个确定的结果为止
-=-=-=-
那么回到汉诺塔的问题
假如ABC三个柱子,你要把A柱子上的x个片移动到C柱子上,那么首先要把A柱子上的x-1个片移动到B柱子上作为中转,然后把最下面一个移动到C柱子上,再把B柱子上的x-1个片移动到C柱子上。假如这是第k步要做的事情,那么第k-1步是要怎么把x-1个从A移动到B,第k-2步是如何把x-2个片从B移动到A,以此类推,一直到只剩一个片就直接移动
package violentCracking;
public class repeat {
public static void main(String[] args) {
// 运用重复检测的方法去做
for (int i = 1; i < 100; i++) {
int a =i*i*i;
int b =a*i;
if ((a+"").length()!=4) {//判断立方长度是否为4
continue;
}
if ((b+"").length()!=6) {//判断4次方长度是否为6
continue;
}
System.out.println("当前年龄"+i+" 年龄的三次方 "+a+" 年龄的四次方 "+b);
}
}
}
得到的结果是
当前年龄18 年龄的三次方 5832 年龄的四次方 104976
当前年龄19 年龄的三次方 6859 年龄的四次方 130321
当前年龄20 年龄的三次方 8000 年龄的四次方 160000
当前年龄21 年龄的三次方 9261 年龄的四次方 194481