我的讲师在测试中告诉我们以下内容:
" 给出以下代码:
int count=0;
static void towersOfhanoi(int n, char source, char target, char spare)
{
count++;
if (n==1)
System.out.println("move a disk from "+source+" to "+target);
else
{
towersOfhanoi(n-1, source, spare, target);
System.out.println("move a disk from "+source+" to "+target);
towersOfhanoi(n-1, spare, target, source);
towersOfhanoi(1, spare, source, target);
towersOfhanoi(n-1, source, spare, target);
在执行了towerofhanoi(11,A,B,C)之后移动的价值是什么?"
我回家编程了这个并且移动次数增加了,在我插入这些代码行之前,我将其称为 A (使用11个磁盘,产生了118097次移动!) :
towersOfhanoi(n-1, spare, target, source);
towersOfhanoi(1, spare, source, target);
towersOfhanoi(n-1, source, spare, target);
在插入这些代码之前,我已将这些代码放在其位置。我将其称为 B (使用11个磁盘,生成2047次移动):
towersOfhanoi(n-1, spare, target, source);
我的问题是, A 中的3行代码做了什么?为什么移动的数量会发生变化,是否有计算移动次数的公式?我知道可以使用"(2 ^ 11)-1"来计算移动量。对于 B 。任何反馈都会有所帮助。
答案 0 :(得分:2)
嗯, B 线是河内塔问题的正确解决方案。 A 而不是 B 的三行正是他们所说的:他们用这些参数递归地调用函数。第一行与 B 相同,所以这是正确的。其他两行在问题方面没有意义。你把它们放在那里,所以问题更多:为什么你这样做?
我猜你想要做以下事情:
if (n==1) {
System.out.println("move a disk from "+source+" to "+target);
} else {
towersOfhanoi(n-1, source, spare, target);
towersOfhanoi(1, source, target, spare);
towersOfhanoi(n-1, spare, target, source);
}
这将是河内塔的另一个正确表达问题,其移动次数与原来的 B 相同。
至于公式:如果我们将n个磁盘的移动次数定义为N(n),则原始解决方案解决方案为移动次数(遵循源代码):
N(n) = N(n-1) + 1 + N(n-1)
= 2 * N(n-1) + 1
= 2 * (2 * (2 * ... (2 * 1 + 1) ... + 1) + 1) + 1)
= 2^(n-1) + 2^(n-2) + 2^(n-3) + ... + 1
= (1 - 2^n) / (1 - 2)
= 2^n - 1
对A代码的类似推理:
N(n) = N(n-1) + 1 + N(n-1) + 1 + N(n-1)
= 3 * N(n-1) + 2
= 3^(n-1) + 2 * (3^(n-2) + ... + 1)
= 3^(n-1) + 2 * (1-3^(n-1)) / (1-3)
= 2 * 3^(n-1) - 1