2017-02-10 8 views
-1

プロジェクトオイラーで質問8をしていて、問題があります。それは言う、 "メイン" java.lang.ArrayIndexOutOfBoundsExceptionスレッドでプロジェクトオイラー#8問題

例外:main.mainで1000 (main.java:19)

私がしようとすると必要な13桁でそれを実行します最後の13桁の文字列 '0420752963450'になり、上記のエラーでクラッシュします。

私はエラーが何を意味し、どこから来ているのか知っていますが、修正できないようです。

私の質問は、この作業を行う方法です。どこが間違っていますか?私はこれを修正しようと数時間を費やしました。オイラー#8にあなたのソリューションの有効性を確認せず

public class main { 

    public static void main(String[] args){ 
    String string = ("7316717653133062491922511967442657474235534919493496983520312774506326239578318016984801869478851843858615607891129494954595017379583319528532088055111254069874715852386305071569329096329522744304355766896648950445244523161731856403098711121722383113622298934233803081353362766142828064444866452387493035890729629049156044077239071381051585930796086670172427121883998797908792274921901699720888093776657273330010533678812202354218097512545405947522435258490771167055601360483958644670632441572215539753697817977846174064955149290862569321978468622482839722413756570560574902614079729686524145351004748216637048440319989000889524345065854122758866688116427171479924442928230863465674813919123162824586178664583591245665294765456828489128831426076900422421902267105562632111110937054421750694165896040807198403850962455444362981230987879927244284909188845801561660979191338754992005240636899125607176060588611646710940507754100225698315520005593572972571636269561882670428252483600823257530420752963450"); 
    char[] charAr = string.toCharArray(); 
    int x = 1; 
    int i = 0; 
    int y = 14; 
    int product = 0; 
    int tempx = 0; 
    int temp = 0; 
    int times = 1; 
    int newLargest = 0; 
    while (tempx <= 999){ 
     tempx = x; 
     times = 1; 
     while (x < (y - 1)){ 
      System.out.print(Integer.parseInt(String.valueOf(charAr[x - 1]))); 
      times = times * Integer.parseInt(String.valueOf(charAr[x - 1])); 
      x++; 
      i++;    
     } 
     System.out.print("\n"); 
     System.out.println(
      "X: " + x + "\t Times: " + times + "\t tempx: " + tempx); 
     x = tempx; 
     x++; 
     y++; 

     if (i == 1000){ 
      i = 0; 
     } 
     temp = product; 
     product = times; 
     //System.out.println(times); 
     if (product > temp){ 
      newLargest = product; 
      //System.out.println(newLargest); 
     } 
     //System.out.println(newLargest); 
    } 
    //System.out.println(newLargest); 
    }  
} 

答えて

1

から条件間に、第2の変更:断ち切るために

while (x < (y - 1) && x < charAr.length+1) 

:に

while (x < (y - 1)) 

あなたが配列の最後のセルに到達しているとき。私はあなただけの場合は、条件whileループ内の追加する必要があると思う

0

:私は正直なエラーを防止するために、あなたのアルゴリズムを検討している

while (x < (y - 1)){ 
    if(x-1 >= charAr.length) break; // add this line 
    System.out.print(Integer.parseInt(String.valueOf(charAr[x - 1]))); 
    times = times * Integer.parseInt(String.valueOf(charAr[x - 1])); 
    x++; 
    i++; 
} 
0

は本当に簡単ですが、私はあなたがしていることを見出しましたあなたは "String.charAt()"メソッドを使用して簡単に数値にアクセスできるときに、なぜそれをchar配列に変換する必要があるのでしょうか?また、私はあなたのプログラムが正しい結果を表示していなかった問題を解決した。私はプロジェクトオイラーの質問8を見て、すぐにこの解決法を提供しました。それはうまくいきます。あなたがどこに間違っていたのか、今後どこで改善すべきかを理解するのに役立ちます。

private static void PE_Problem_8() 
    { 
     String NumbersArray = "73167176531330624919225119674426574742355349194934" + 
       "96983520312774506326239578318016984801869478851843" + 
       "85861560789112949495459501737958331952853208805511" + 
       "12540698747158523863050715693290963295227443043557" + 
       "66896648950445244523161731856403098711121722383113" + 
       "62229893423380308135336276614282806444486645238749" + 
       "30358907296290491560440772390713810515859307960866" + 
       "70172427121883998797908792274921901699720888093776" + 
       "65727333001053367881220235421809751254540594752243" + 
       "52584907711670556013604839586446706324415722155397" + 
       "53697817977846174064955149290862569321978468622482" + 
       "83972241375657056057490261407972968652414535100474" + 
       "82166370484403199890008895243450658541227588666881" + 
       "16427171479924442928230863465674813919123162824586" + 
       "17866458359124566529476545682848912883142607690042" + 
       "24219022671055626321111109370544217506941658960408" + 
       "07198403850962455444362981230987879927244284909188" + 
       "84580156166097919133875499200524063689912560717606" + 
       "05886116467109405077541002256983155200055935729725" + 
       "71636269561882670428252483600823257530420752963450"; 

     long PermanentTotal = 0; 
     try { 
      for (int i = 0; i < NumbersArray.length(); i++) { 
       Character firstNum = NumbersArray.charAt(i); 
       long TemporaryTotal = Long.parseLong(firstNum.toString()); 
       for (int j = i + 1; j <= i + 12; j++) { 
        if(j < NumbersArray.length()) { 
         Character secondNum = NumbersArray.charAt(j); 
         if (secondNum.toString().length() > 0) { 
          TemporaryTotal *= Long.parseLong(secondNum.toString()); 
         } 
        } 
       } 
       if (TemporaryTotal > PermanentTotal) { 
        PermanentTotal = TemporaryTotal; 
       } 
      } 
     }catch (Exception e){ 
      e.printStackTrace(); 
     } 
     System.out.println("largest product: "+ PermanentTotal); 
    } 
0

コードを複雑にしているようです。簡単にして、何が起こるか見てみましょう。

まずは、だから、多くの方が良いでしょう

static int calculateValue(int x, int y, char[] charAr) { 
    int times = 1; 
    int newx = x; 
    while(newx < (y -1)) { 
     int value = Integer.parseInt(String.valueOf(charAr[x-1]))); 
     times = times * value; 
     newx++; 
    } 
    return times; 
} 

public static void main(String[] args){ 
    String string = ("7316717653133062491922511967442657474235534919493496983520312774506326239578318016984801869478851843858615607891129494954595017379583319528532088055111254069874715852386305071569329096329522744304355766896648950445244523161731856403098711121722383113622298934233803081353362766142828064444866452387493035890729629049156044077239071381051585930796086670172427121883998797908792274921901699720888093776657273330010533678812202354218097512545405947522435258490771167055601360483958644670632441572215539753697817977846174064955149290862569321978468622482839722413756570560574902614079729686524145351004748216637048440319989000889524345065854122758866688116427171479924442928230863465674813919123162824586178664583591245665294765456828489128831426076900422421902267105562632111110937054421750694165896040807198403850962455444362981230987879927244284909188845801561660979191338754992005240636899125607176060588611646710940507754100225698315520005593572972571636269561882670428252483600823257530420752963450"); 
    char[] charAr = string.toCharArray(); 
    int x = 1; 
    int i = 0; 
    int y = 14; 
    int product = 0; 
    int temp = 0; 
    int times = 1; 
    int newLargest = 0; 
    while (tempx <= 999){ 
     times = calculateValue(x, y, charAr); 
     if(times > newLargest) { 
      newLargest = times; 
     } 
     x++; 
     y++; 
    } 
} 

なり

tempx = x; 
times = 1; 
while (x < (y - 1)){ 
    System.out.print(Integer.parseInt(String.valueOf(charAr[x - 1]))); 
    times = times * Integer.parseInt(String.valueOf(charAr[x - 1])); 
    x++; 
    i++;    
} 
System.out.print("\n"); 
System.out.println(
    "X: " + x + "\t Times: " + times + "\t tempx: " + tempx); 
x = tempx; 

外の機能を作りましょう。今、数学者になり、0から数え始めます。そして、 '14'の定数を作って、yを取り除くことができます。私たちはそれを捜しているので、文字列の長さから外れないようにしましょう。それは999かもしれませんが、なぜ安全でないのか、string.length()を使用して実際の値を使用してください。そして、その奇妙な配列の代わりに直接文字列を使用してください。

int calculateValue(int x, String theString) { 
    int times = 1; 
    int i = x; // traditionally, we use 'i' for loop variables. 
    while(i < (x + FOURTEEN)) { 
     int value = Integer.parseInt(theString.charAt(i)); 
     times = times * value; 
     i++; 
    } 
    return times; 
} 

public static void main(String[] args){ 
    String string = ("7316717653133062491922511967442657474235534919493496983520312774506326239578318016984801869478851843858615607891129494954595017379583319528532088055111254069874715852386305071569329096329522744304355766896648950445244523161731856403098711121722383113622298934233803081353362766142828064444866452387493035890729629049156044077239071381051585930796086670172427121883998797908792274921901699720888093776657273330010533678812202354218097512545405947522435258490771167055601360483958644670632441572215539753697817977846174064955149290862569321978468622482839722413756570560574902614079729686524145351004748216637048440319989000889524345065854122758866688116427171479924442928230863465674813919123162824586178664583591245665294765456828489128831426076900422421902267105562632111110937054421750694165896040807198403850962455444362981230987879927244284909188845801561660979191338754992005240636899125607176060588611646710940507754100225698315520005593572972571636269561882670428252483600823257530420752963450"); 
    int x = 0; 
    int newLargest = 0; 
    while (x < string.length()){ 
     int times = calculateValue(x, string); 
     if(times > newLargest) { 
      newLargest = times; 
     } 
     x++; 
    } 
} 

今、私たちはまだバグを修正していませんが、少なくともこれについては少し理由があります。それは限界を超えているので起こっている。 xの最大サイズは999です。 'i'の最大値はx + FOURTEENまたは1013です。 これは私たちの配列よりも長くなります。だから私たちはそれが起こらないことを保証するためにそれを打破する必要があります。 これを実行するには、calculateValueが文字列の最後に到達すると停止するようにcalculateValueを修正します。

int calculateValue(int x, String theString) { 
    int times = 1; 
    int i = x; // traditionally, we use 'i' for loop variables. 
    while(i < (x + FOURTEEN) && i < theString.length()) { 
     int value = Integer.parseInt(theString.charAt(i)); 
     times = times * value; 
     i++; 
    } 
    return times; 
} 
関連する問題