2016-01-28 2 views
-1

Мой код занимает слишком много времени для запуска. То, что я пытался сделать, - это цикл до большого числа, а затем цикл ip для него, чтобы найти его сумму, а затем цикл для проверки делителей. Как мне его оптимизировать?Как уменьшить время выполнения Q12 Project Euler

public class Q12 
{ 

    public static void main(String[] args) 
    { 

     int answer=5; 
     Boolean check=false; 
     int sum=0; 
     int counter=0; 
     int kk=0; 
     while(check==false) 
     { 
      loop: 
      for(int i=1;i<50000000;i++) 
      { 
       sum=0; 
       counter=0; 

       for(int j=0;j<i;j++) 
       { 
        sum=j+sum; 
       } 

       for(int k=1;k<sum;k++) 
       { 
        if(sum%k==0) 
        { 
         counter=counter+1; 
        } 

       } 

       if(counter>=501) 
       { 
        check=true; 
        break loop; 
       } 


      } 


     } 



    } 

} 

Благодаря

+0

Использовать математику для оптимизации, например. сумма всех целых значений между a и b должна легко вычисляться без циклирования. – Thomas

+0

Вы пересчитываете сумму из '0' каждый раз, когда вы зацикливаете через' i', просто храните ее вне цикла и добавляете 'i' на каждой итерации цикла. Кроме того, вам не нужно запускать 'i' на' 1'. Есть более эффективные способы получить факторы числа, а не проходить и тестировать их один за другим. Например, если вы знаете, что '2' является фактором, то вы также знаете, что' n/2' является фактором. Кроме того, вы можете остановить 'k' в' sum/2', так как это самый большой возможный фактор (исключая сам номер). – mikeyq6

ответ

0
  1. Это не очевидно, что код ваш должен делать, так что я сомневаюсь, какой я могу оптимизировать там ...

  2. Эта часть:

    check=true; 
    break loop; 
    

    выполняет разблокировку и переходит на

    loop: 
    for(int i=1;i<50000000;i++) 
    

    , который снова запустит внутренний цикл с повторениями 50000000, после того, как check уже был оценен. Это намеренное поведение?

  3. Здесь:

    sum=0; 
    counter=0; 
    
    for(int j=0;j<i;j++) 
    { 
        sum=j+sum; 
    } 
    

    вы можете использовать кэширование. Как:

    long[] precalc = new long[50000000]; 
    
    int answer=5; 
    Boolean check=false; 
    int sum=0; 
    int counter=0; 
    int kk=0; 
    while(check==false) 
    { 
        loop: 
        for(int i=1;i<50000000;i++) 
        { 
         sum = precalc [i]; 
         if (sum == 0) { 
          precalc[i] = sum = (precalc[i - 1] + i); 
         } 
    
         counter=0; 
    
         ... 
    
  4. Кроме того, я предлагаю вам использовать long -s вместо int -s, так как возможно арифметическое переполнение.