2017-12-08 14 views
0

このプログラムでは、配列要素と配列要素のサイズはユーザーから取得されます。ユーザー提供の整数配列から1,2,3番目に大きい番号

このコードは、すべてのI試みた場合ではなく、配列の大きさが4である場合、通過することと要素を通過している{5,5,5,2}

ここ

出力5 5
なければなりませんしかし、私は得ている2 2 5

私はこの部分に問題があることがわかります。

else if((max1 == max2 && max2 == max3 && max1 == max3) && x[i] < max2) 
       { 
        max2 = x[i]; 
        if(max2 < max3) 
        { 
         max3 = max2; 
        } 
       } 

どのようにすればこの問題をアレイのみで解決できますか?コレクションにソリューションが必要ない。

import java.util.*; 
    class ThirdLargest 
    { 
     public static void main(String[] args) 
     { 
      Scanner sc = new Scanner(System.in); 
      System.out.println("Enter size for array: "); 
      int size = sc.nextInt(); 
      int[] x = new int[size]; 
      for(int i = 0; i < x.length; i++) 
      { 
       System.out.println("Enter elements for array: "); 
       x[i] = sc.nextInt(); 
      } 
      System.out.println("Array is: "); 
      for(int i = 0; i < x.length; i++) 
      { 
       System.out.print(x[i] +" "); 
      } 
      System.out.println(); 
      if (x.length >= 3) 
      { 
       int max1 = x[0], max2 = x[0], max3 = x[0]; 
      for (int i = 1; i < x.length; i++) 
      { 
        if(x[i] > max1) 
        { 
         max3 = max2; 
         max2 = max1; 
         max1 = x[i]; 
        } 
        else if(x[i] > max2) 
        { 
         max3 = max2; 
         max2 = x[i]; 
        } 
        else if (x[i] > max3) 
        { 
         max3 = x[i]; 
        } 
        else if((max1 == max2 && max2 == max3 && max1 == max3) && x[i] < max2) 
        { 
         max2 = x[i]; 
         if(max2 < max3) 
         { 
          max3 = max2; 
         } 
        } 
        else if(max2 == max3 && x[i] < max3) 
         { 
          max3 = x[i]; 
         } 
       } 
      System.out.println("3rd, 2nd and 1st maximum: " + max3 +" "+max2+" "+max1); 
      } 
      else 
      { 
       System.out.println("Array size is short");  
      }  
     } 
    } 

答えて

0

問題は、配列の繰り返し整数が一意の要素として追跡されないということです。

あなたが紙の上に配列x = [5, 5, 5, 2]を見ると、あなたが値5の3つのユニークint要素があることがわかりますので、最大3は5, 5, 5する必要がありますが、それはで値2に達したときにテストが、今の道アレイの端部は、それがmax3max2、及びmax1各々はx[0]x[1]、及びx[2]の値5の三別個intsを表すことを知りません。

問題は、このコードセクションにここで見ることができる。

... 

else if ((max1 == max2 && max2 == max3 && max1 == max3) && x[i] < max2) { 
    max2 = x[i]; 
    if (max2 < max3) { 
     max3 = max2; 
    } 
} else if (max2 == max3 && x[i] < max3) { 
    max3 = x[i]; 
} 

... 

これは二つの理由のために動作しない:最初if/elseブロック内

  1. は、max2max3両方が変更されますしたがって、他のif/elseブロックは、の将来の間に動作します。ループの繰り返しですが、問題はです。これは、次の繰り返しがあることを前提としています。。上記のコードブロックがの最後ののループで実行されている場合は機能しません。 [5, 5, 5, 2]。

    • (サイドノート)max1であれば、max2、及びmax3は、行の後、x[i] < max2全て等しく、かつ:

      max2 = x[i]; 
      

      max2常になり未満max3そう試験if (max2 < max3) {必要ない。

  2. 試験max1 == max2 && max2 == max3 && max1 == max3max2 == max3は、ケース処理されません:

    • max1max2を、そして例えば、max3は全て同じであるが、各々は、アレイ内の異なる要素を表します。ユニークは2に再割り当てされmax2max3、のトラックを保持していないので、これはforループ最後のものであるため、forループでi = 3そしてmax1は、x[0]を表すことができmax2x[1]を表すことができ、そしてmax3x[2]を表すことができますが[5, 5, 5, 2]、実行すると、出力は2, 2, 5になります。

    • max2およびmax3は等しいが、それぞれがアレイ中の異なる要素を表す。 [7, 7, 8, 2]ため、forループで場合i = 3max2はユニークがmax3、のトラックが2に再割り当てされ、出力が2, 7, 8代わりに7, 7, 8で維持されていないためx[1]やはりを表しx[0]max3を表します。

明確にするには:

  • あなたは2はインデックス4、理由は上記の理由のプログラムでしょう出力2, 2, 5で発生配列[5, 5, 5, 5, 2]をテストした場合。
  • あなたは2はインデックス3で発生配列[5, 5, 5, 2, 5]をテストした場合、プログラムだろう出力2, 5, 5一つだけ52後に表示されることがありますので。
  • あなたは2後に発生する2 5sがあるので2はインデックス2、プログラムでしょう出力5, 5, 5で発生配列[5, 5, 2, 5, 5]をテストした場合。最後に、max1,max2、およびmax3はすべて互いに等しい。5
  • あなただけの前の配列である配列[5, 5, 2, 5, 5, 3]をテストしたが、3と、プログラムは出力3, 3, 55、ときforループでi = 5max1max2、およびmax3すべてが互いに等しいので、希望、最後に追加している場合プログラムでは、最初はすべてがx[0]に設定されているためです。

は今、プログラムが動作しない理由を理解することを、私は約読んで、この問題を解決するためのより良い方法は、最初のIntegerラッパークラスを使用して可能な限り低い値にmax1max2、およびmax3を初期化するだろうと信じてそれhere

int max1, max2, max3; 
max1 = max2 = max3 = Integer.MIN_VALUE; 
0123で

int max1 = x[0], max2 = x[0], max3 = x[0]; 

を交換してくださいあなたはそれを解決するための非常に接近していたと

else if ((max1 == max2 && max2 == max3 && max1 == max3) && x[i] < max2) { 
    max2 = x[i]; 
    if (max2 < max3) { 
     max3 = max2; 
    } 
} else if (max2 == max3 && x[i] < max3) { 
    max3 = x[i]; 
} 

は、代わりに1

for (int i = 0; i < x.length; i++) { 

の今指数0から始まり、最後の2つのif/elseのブロックを削除するには、最後のforループを変更しますバグを修正するためにはわずかな変更しか必要ありません。

これは役に立ちました、そして歓声です!

1

このコードは人間が読めるものではありません。デバッグしようとしている間、このコードに固執します。 まず、このコードをメソッドに分割する必要があります。一つのメソッドですべてをやろうとしないでください。あなたは、最大値の計算を行っているロジックからユーザーからint配列を受け取るロジックを切り離す必要があります。例:

public int[] threeMaximumValuesFrom(int[] array) { 
    int[] sorted = sortArray(array); 
    int[] result = { 
     sorted[array.length - 1]; 
     sorted[array.length - 2]; 
     sorted[array.length - 3]; 
    } 
    return result; 
} 

private int[] sortArray(int[] array) { 
    //when you don't want to use jdk sort implement your own 
    //in any way other parts of code should knows nothing about it 
    Arrays.sort(array); 
    return array; 
} 
0
int[] numbers = {5, 5, 5, 2}; 
Arrays.stream(numbers).sorted().skip(numbers.length - 3).forEach(System.out::println); 

私たちはにarrayLengthをスキップし、その後、我々はそれを並べ替え、あなたの配列のうちの流れを作る - n個の要素(nはあなたがプリントアウトしたいどのように多くの最大数)と我々が残っている数字のそれぞれを印刷します。

関連する問題