我实际上在做一个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中的值,基本上使您进入一个无限循环。

07-28 02:56
查看更多