我正在解决欧拉项目问题14 https://projecteuler.net/problem=14使用java。我并不是寻求帮助解决问题。我已经解决了,但我遇到了一些我无法弄清楚的事情。
问题是这样的:
为正集合定义以下迭代序列
整数:
n = n/2,如果 n 是偶数
n = 3n + 1,如果 n 是奇数
使用上面的规则并从 13 开始,我们生成以下内容
顺序:
13 -> 40 -> 20 -> 10 -> 5 -> 16 -> 8 -> 4 -> 2 -> 1。这里,链的长度是10个数字。
找出 1,000,000 以下的起始数字,从而产生最长的链。
所以我写了这段代码:
public class Euler014 {
public static void main(String[] args){
int maxChainCount = 0;
int answer = 0;
int n;
int chainCount = 1;
for(int i = 0; i < 1000000; i++){
n = i;
while(n > 1){
if(n%2 == 0){ //check if even
n /= 2;
}else{ //else: odd
n = 3*n + 1;
}
chainCount++;
}
if(chainCount > maxChainCount){ //check if it's the longest chain so far
maxChainCount = chainCount;
answer = i;
}
chainCount = 1;
}
System.out.println("\n\nLongest chain: i = " + answer);
}
}
这给了我答案 910107,这是错误的。
但是,如果我将 n 变量的类型更改为double n
它运行并给出答案 837799,这是正确的!
这真的让我很困惑,因为我根本看不出有什么区别。我明白如果我们使用int
进行除法运算时,我们可能会在无意的情况下对数字进行四舍五入。但在这种情况下,我们总是检查是否n
在除以 2 之前可以被 2 整除。所以我认为使用整数是完全安全的。我没看到什么?
这是完整的代码,如果您想亲自查看,请复制、粘贴并运行它。尽管进行了多次迭代,它还是在几秒钟内运行。 =)
你的问题是溢出。如果你改变int n
to long n
,你会得到正确的答案。
请记住:序列中的数字可以是真的很大。太大了,溢出来了int
的范围。但不是(在这种情况下)double
's, or long
's.
在链条中的某一点,n
is 827,370,449
你按照3n + 1
分支。这个值想要成为2,482,111,348
,但它超出了容量int
(这是2,147,483,647
在积极的领域)并带你去-1,812,855,948
。事情从那里开始向南发展。 :-)
所以你的理论是你可以使用整数(我应该说integral) 数字是正确的。但他们必须有完成任务的能力。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)