2013-12-24 7 views
1

Я на самом деле работаю над 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 

где ток дает мне номер его получил факторы от и, очевидно, то факторы является ряд факторов. Я не даю никаких ошибок и единственным предупреждением из -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; 
} 
+4

Вы можете выполнить это поэтапно с помощью отладчика, чтобы определить, что он делает (и почему). –

+0

Первый цикл 'for' обращается к недопустимой позиции в' numtocheck', когда 'i == n || i == n + 1'; тест 'x! = 0' будет оцениваться как true, и вы присвойте' x' 'numtocheck [n]', и в следующей итерации вы сделаете то же самое для 'numtocheck [n + 1]', ошибок. –

+1

int numtocheck [n]; поэтому размер равен n, но в цикле for; для (i = 0; i <= n + 1; i ++) ... возможно, вы должны получить ошибку сегментации, поскольку она из стеков, это может быть переписывание данных по массиву факторов – hevi

ответ

1

Вот некоторые моменты, чтобы рассмотреть (пункт 5 является большой проблемой):

1) Вы забыли точку с запятой так что этот код не будет компилироваться, основываясь на этом, я немного обеспокоен вы не имеете все, что в здесь дословно, как вы его ...

int h=1,x=0,p=0,n=5000,m=500,m2=600,twitch=0 //<- ; needed 

2), как указано в комментариях вашего первого цикла переполнения массива:

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), так как вы не инициализировать 0 й элемент numtocheck это означает, что есть данные для мусора в 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 около 2346 p больше, чем переполняет 600 элементов в factors[], и вы начинаете делать плохие вещи. Это вызывает неопределенное поведение. На одной имплантации в Linux это вызвало очень хороший набор ошибок.На другом в Windows это просто записывает значения в numtocheck, в основном заставляя вас перейти в бесконечный цикл.

+0

Майк, спасибо, это должно быть самой полезной информацией, которую я получил от кого-либо для C. Сейчас я работаю над обучением C и C++. В большинстве случаев я работал с python. Я стараюсь не делать слишком много предположений, например, не требуя выражения else. Я думал, что я просил, чтобы он почему-то был там. Опять же, спасибо кучу. – Tristen

Смежные вопросы