我有这个代码用于计算fibonacci
中的python
数字。它起作用并给出预期的结果。但是当我将它翻译成Java
时,它失败了。知道这里出了什么问题吗?
在python
:
def fib3(n):
a,b=0,1
while n>0:
a,b=b,a+b
n-=1
return a
fib3(12) --> 144
在Java
:
public static int fib2(int n){
int a = 0;
int b =1;
while(n-- >0){
a=b;
b=a+b;
}
return a;
}
fib2(12) --> 2048
答案 0 :(得分:26)
在本节中:
a=b;
b=a+b;
您将b
分配给a+b
,但a
已经b
。所以你真的加倍b
最简单的解决方案是临时变量:
public static int fib2(int n){
int a = 0;
int b =1;
while(n-- >0){
int old_a;
old_a = a;
a=b;
b=old_a+b;
}
return a;
}
在python中,a, b = b, a + b
在将新值分配给变量之前自动存储中间tuple
,而在Java中,您需要明确它们
分解Python的指令,a, b = b, a + b
正在执行此反汇编:
5 17 LOAD_FAST 1 (b)
20 LOAD_FAST 0 (a)
23 LOAD_FAST 1 (b)
26 BINARY_ADD
27 ROT_TWO
28 STORE_FAST 0 (a)
31 STORE_FAST 1 (b)
从更简单的意义上说,保持python,这是一个过程:
temp_tuple = (b, a + b)
a, b = temp_tuple
答案 1 :(得分:9)
问题是您必须同时从b
到a
的一个值分配给{{1 } b
和a
的总和。得到错误的同时交换并得到错误的答案。
根据Python代码的精神,我提出:
b
这可以在添加的同时有效地进行交换(严格来说不是,但它足够好)。请注意,这是定义良好的 Java,因为该语言精确定义了运算符的求值顺序,这与C和C ++(其中允许使用上述代码的等价物)使恶魔飞出您的鼻子由于是未定义的行为)。
好吧,如果它确实让你遇到了鼻子恶魔的问题,我建议将来不要使用那个编译器。但是你无法保证获得正确的fib()函数......
答案 2 :(得分:6)
a = b;
b = a+b;
这会计算b = 2*b
,因为a
的值会在您计算b
的新值时被覆盖。替换为:
t = b;
b = a+b;
a = t
答案 3 :(得分:5)
a=b;
b=a+b;
......是问题所在。在将a
添加到b
之前,您需要保存{{1}}的旧值。
答案 4 :(得分:5)
代码不等同,依赖于python在一行a,b=b,a+b
中分配多个基元的能力;你需要一个临时变量 -
public static int fib2(int n){
int a = 0;
int b =1;
while(n-- >0){
int t = b; // <-- to hold the original value of b.
b = a + b;
a = t;
}
return a;
}
答案 5 :(得分:3)
在java中 - 当你写“a = b; b = a + b;”时你基本上是说a应该等于是,然后(因为'a'现在等于'b'),'b'应该是它原来的两倍。 有两种方法可以解决这个问题。 1)您可以继续使用最初使用的功能,然后在更改“a”之前创建一个int'temp'来存储'a'。 2)你也可以做我宁愿做的事情(对于像斐波那契这样的算法,这将花费更多的时间,对于真实世界的应用程序通常是一个糟糕的想法)是使用一个会调用自身的递归函数。
通常看起来像下面这样。
public static int fib2(int n){
if(n<=0){return 0;}
if(n<2){return 1;}
else{ return fib2(n-1)+fib2(n-2);}
}
这可能不是确切的代码,但非常类似。希望这很有用!