我实际上在做一个projecteuler.com problem (#12 specifically)程序,当我没有任何编译错误的时候,我想我已经搞定了。
它运行,并给我几个结果,似乎是正确的,但它没有完成。我用C的时间不长,所以我可能忽略了一些我不熟悉的东西。有人能告诉我为什么停下来吗?它给了我高达12.5米的正确三角形数字。我也很乐意接受评论中的优化建议。
结果是第一个,即使在几个小时后,它也没有超过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给出了它从中得到的因子的数目,显然,那么因子就是因子的数目。我没有给我任何错误,唯一的警告是-沃尔,我没有实际使用“无用”的变量为任何事情。
#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;
}
最佳答案
以下是一些需要考虑的问题(第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个元素,这意味着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
配对,不需要。5)好吧,这里有个大问题:
if(flag1==0){
factors[p]=j;
p+=1;
}
else if(flag2==0){
factors[p]=k;
p+=1;
}
factors[]
是一个包含600个元素的数组,您可以使用p
访问一个最初为0的值,但每次它进入这些检查时都会递增。当您的number
大约2346p
超过了factors[]
中的600个元素的溢出量时,您就开始做坏事了。这会导致未定义的行为。在Linux中的一次植入中,这导致了一个非常好的setfault。在Windows中的另一个窗口上,这个简单地重写了numtocheck
中的值,基本上使您进入一个无限循环。