项目Euler#14:这段代码出了什么问题?

时间:2014-01-03 04:43:26

标签: c

这与“项目欧拉问题14”

有关

我认为,我的逻辑和代码足够好,但可能需要几秒钟才能给出答案。 但是,当我运行此代码时,程序会在“starting_number”大约为103152时停止(我不记得确切的数字)。

任何人都可以看看这段代码,并告诉我这段代码的位置和错误。

以下是代码:

#include<stdio.h>
int starting_number;
int number_of_terms;
int j=0,k=0;
int term;

int main(){
  for(starting_number=2;starting_number<1000000;starting_number++){
    term = starting_number;
    number_of_terms = 1;

    while(1){
      {
        if(term%2==0){
          term = term/2;
          number_of_terms++;
        } else if(term%2!=0){
          term = 3*term + 1;
          number_of_terms++;
        }
      }
      if(term == 1) break;    
    }


    if(j>=number_of_terms)   //finding which chain is longer
      j=j;
    else if(j< number_of_terms) {
      j= number_of_terms;
      k=starting_number;
    }

    printf("\n%d",starting_number);
  } 

  printf("\n%d(%d)\n",k,j);
  return 0;
}

1 个答案:

答案 0 :(得分:4)

这个有点棘手,但你的问题在这里:

if(term == 1) break;

如果变量term变得非常大(因为它很容易),那么它可能会溢出int数据类型。

发生这种情况时term变为否定。负奇数的C语言模数本身是负的。因此,永远不会满足循环的结束条件。

使用较大的数据类型(例如unsigned long long

)解决此问题

您的代码的错综复杂版本将如下所示。请注意,我已经消除了全局变量(main函数之外的变量),因为全局变量are evil。我用一个使用结束条件的循环替换了你的无限while循环。我减少了while循环中的代码重复。我已经删除了j=j案例。由于printf是一个很慢的运行功能,我已经注释掉了prinft循环中的for,这大大提高了运行时间。

#include <stdio.h>

int main(){
  int number_of_terms;
  unsigned long long term;
  int j=0,k=0;

  for(int starting_number=2;starting_number<1000000;++starting_number){
    term = starting_number;
    number_of_terms = 1;

    while(term!=1){
      if(term%2==0)
        term /= 2;
      else
        term = 3*term + 1;
      number_of_terms++;
    }

    if(j<number_of_terms){   //finding which chain is longer
      j = number_of_terms;
      k = starting_number;
    }

    //printf("\n%d",starting_number);
  } 

  printf("\n%d(%d)\n",k,j);
  return 0;
}

事实上,使用unsigned long long解决了这个问题。