我实际上正在研究projecteuler.com problem (#12 specifically),当我没有收到任何编译错误时,我认为我已将其固定。 它运行并给我几个看似正确的结果,但它没有完成。我没有长时间使用C,所以我可能忽略了一些我不熟悉的东西。有人能告诉我为什么它会停止吗?它给了我正确的三角形数字,高达12.5M。我也很乐意接受评论中的优化建议。 结果是第一个,即使在几个小时之后它没有超过第一个数字,有30个因素,它发现相当快。 它从我的代码中给出了这个:
$ ./euler12
Current= 1
Factors= 1
Current= 3
Factors= 2
Current= 6
Factors= 4
Current= 28
Factors= 6
Current= 36
Factors= 9
Current= 120
Factors= 16
Current= 300
Factors= 18
Current= 528
Factors= 20
Current= 630
Factors= 24
Current= 1008
Factors= 30
其中,Current给出了它得到因子的数字,显然那么因子是因子的数量。我没有给我任何错误,-Wall唯一的警告是我实际上并没有使用“无用”变量。
#include <stdio.h>
#include <time.h>
/*
Tristen
euler12.c
December 23, 2013
What's the value of the first triangle number to have over 500 divisors?
*/
int main(void)
{
/*---------Variables----------*/
time_t t1 = time(NULL);
int g,l,i,j,k,t,number,val,flag1,flag2;
int h=1,x=0,p=0,n=5000,m=500,m2=600,twitch=0
int answer=0,count=0,useless=0,linlen=0; /*modify n to change size*/
/*----------Arrays------------*/
int numtocheck[n];
int factors[m2];
/*find triangle numbers*/
for(i=0;i<=n+1;i++){
x+=i;
if(x!=0){
numtocheck[i]=x;
}
else{
useless=0;
}
}
/*begin checking for factors*/
while(twitch!=1){
count=0;
for(l=1;l<m2;l++){
factors[l]=0;
}
number=numtocheck[h];
for(j=0;j<=number;j++){
for(k=0;k<=number;k++){
val=j*k;
if(val==number){
flag1=0,flag2=0;
for(g=0;g<m2;g++){
if(factors[g]==j){
flag1=1;
}
else if(factors[g]==k){
flag2=1;
}
else{
useless=0;
}
}
if(flag1==0){
factors[p]=j;
p+=1;
}
else if(flag2==0){
factors[p]=k;
p+=1;
}
else{
useless=0;
}
}
}
}
for(l=0;l<m2;l++){
if(factors[l]!=0){
count+=1;
}
}
if(count>=m){
answer=number;
printf("Current= %d\n",number);
printf("Factors= %d\n",linlen);
twitch=1;
}
else{
if(count>linlen){
linlen=count;
printf("Current= %d\n",number);
printf("Factors= %d\n",linlen);
}
else{
useless=0;
}
}
h+=1;
}
time_t t2 = time(NULL);
t=t2-t1;
printf("Survey says %d\n", answer);
printf("time %d\n", t);
getchar();
return 0;
}
答案 0 :(得分:1)
以下是需要考虑的一些要点(第5点是最大的问题):
1)你忘记了一个分号,所以这段代码不会编译,基于此,我有点担心你没有把这里的所有内容逐字记录下来......int h=1,x=0,p=0,n=5000,m=500,m2=600,twitch=0 //<- ; needed
2)如评论中所述,你的第一个for循环溢出了数组:
int n=5000;
int numtocheck[n];
/* so numtocheck[] goes from 0 to 4999 */
/*find triangle numbers*/
for(i=0;i<=n+1;i++){ // this loops from 0 to 5001
所以这需要:
for(i=0;i<n;i++){
3)因为你没有初始化numtocheck
的0 th 元素,这意味着numtocheck[0]
中存在垃圾数据。同样的事情后来factors[0]
,后者是好的,因为你写了它,但它只是要小心。
4)你使用useless
来避免空else
个案例......就像你恰当地命名它一样,这是无用的。如果您没有任何事情可做,请不要做任何事情。
例如,而不是写这个:
if(count>linlen){
linlen=count;
printf("Current= %d\n",number);
printf("Factors= %d\n",linlen);
}
else{
useless=0;
}
只需删除else
,if
可以 与else
配对,它不会 < em>需要 。
5)好的,这是大问题:
if(flag1==0){
factors[p]=j;
p+=1;
}
else if(flag2==0){
factors[p]=k;
p+=1;
}
factors[]
是一个包含600个元素的数组,您可以使用p
访问一个最初为0的值,但每次进入其中任何一个检查时都会递增。当你的number
大约是2346 p
时,factors[]
中的600个元素溢出,你开始做坏事。这会导致未定义的行为。在Linux上的一次植入,这引起了一个非常好的固定故障。在Windows中的另一个中,这只是简单地在numtocheck
中编写了值,基本上让你进入无限循环。