web-dev-qa-db-ja.com

配列の最小値と最大値を見つけるためのInteger.MAX_VALUEおよびInteger.MIN_VALUEの説明

Integer.MAX_VALUEInteger.MIN_VALUEが配列の最小値と最大値を見つけるのにどのように役立つかを理解していないようです。

最小値と最大値を見つけるときに、このメソッド(以下の擬似コード)がどのように機能するかを理解しています。

max = A[0], min = A[0]
for each i in A
  if A[i] > max then max = A[i]
  if A[i] < min then min = A[i] 

しかし、この方法に関しては、Integer.MAX_VALUEInteger.MIN_VALUEの目的がわかりません。

import Java.util.Scanner;

class MyClass {

    public static void main(String[] args) {

        int[] numbers; // declaring the data type of numbers
        numbers = new int[3]; //assigning the number of values numbers will contain
        int smallest = Integer.MAX_VALUE, largest = Integer.MIN_VALUE;

        Scanner input = new Scanner(System.in);

        System.out.println("Please enter 3 numbers");

        for(int counter = 0; counter<numbers.length;counter++) {
            numbers[counter] = input.nextInt();
        }

        for(int i = 0; i<numbers.length; i++) {
            if(numbers[i]<smallest)
                smallest = numbers[i];
            else if(numbers[i]>largest)
                largest = numbers[i];
        }

        System.out.println("Largest is "+largest);
        System.out.println("Smallest is "+smallest);
    }

}
  • System.out.println(Integer.MAX_VALUE)は2147483647を返します
  • System.out.println(Integer.MIN_VALUE)は-2147483648を返します

では、比較においてInteger.MIN_VALUEとInteger.MIN_VALUEはどのような目的に役立つのでしょうか?

25
Tia

しかし、この方法については、Integer.MAX_VALUEとInteger.MIN_VALUEの目的がわかりません。

smallestInteger.MAX_VALUEに設定し、largestInteger.MIN_VALUEに設定して開始することで、smallestおよびlargestにまだ値がない特別なケースについて後で心配する必要がなくなります。調べているデータの最初の値が10である場合、numbers[i]<smallestはtrueになり(10<Integer.MAX_VALUEであるため)、smallest10に更新します。同様に、numbers[i]>largest10>であり、trueを更新するため、Integer.MIN_VALUElargestになります。等々。

もちろん、これを行うときは、調べているデータに少なくとも1つの値があることを確認する必要があります。そうしないと、smallestおよびlargestに暗号化された数字が表示されます。


ポイントOnome Sot はコメントに含まれます:

...配列の最初の項目が他の項目よりも大きい場合、else-ifステートメントにより、最大の項目は常にInteger.MIN_VALUEになります。

それは本当です。以下は、問題を示すより単純な例です( live copy ):

public class Example
{
    public static void main(String[] args) throws Exception {
        int[] values = {5, 1, 2};
        int smallest = Integer.MAX_VALUE;
        int largest  = Integer.MIN_VALUE;
        for (int value : values) {
            if (value < smallest) {
                smallest = value;
            } else if (value > largest) {
                largest = value;
            }
        }
        System.out.println(smallest + ", " + largest); // 1, 2 -- WRONG
    }
}

修正するには、次のいずれかを実行します。

  1. elseを使用しない、または

  2. 最初の要素に等しいsmallestおよびlargestで開始し、else ifを維持しながら残りの要素をループします。

次に、2番目の例( live copy )を示します。

public class Example
{
    public static void main(String[] args) throws Exception {
        int[] values = {5, 1, 2};
        int smallest = values[0];
        int largest  = values[0];
        for (int n = 1; n < values.length; ++n) {
            int value = values[n];
            if (value < smallest) {
                smallest = value;
            } else if (value > largest) {
                largest = value;
            }
        }
        System.out.println(smallest + ", " + largest); // 1, 5
    }
}
31
T.J. Crowder

任意の値(たとえばint smallest = 9999, largest = 0)で変数を初期化する代わりに、その数値型(つまりint smallest = Integer.MAX_VALUE, largest = Integer.MIN_VALUE)で表現できる最大値と最小値で変数を初期化する方が安全です。

整数配列にInteger.MAX_VALUEより大きくInteger.MIN_VALUEより小さい値を含めることはできないため、コードはすべてのEdgeケースで機能します。

14
Salman A

最小/最大値を極端に反対に初期化することで、入力の値のエッジのケースを回避します:実際には、最小/最大のいずれかがそれらの値の1つです(入力がこれらの値の1つのみで構成される場合) )、または正しい最小/最大が見つかります。

プリミティブ型mustには値があることに注意してください。オブジェクト(つまりInteger)を使用した場合、値をnullに初期化し、最初の比較のためにその特殊なケースを処理できますが、余分な(不要な)コードが作成されます。ただし、これらの値を使用することで、ループコードは最初の比較のエッジケースを心配する必要がありません。

別の代替方法は、両方の初期値を入力配列の最初の値に設定し(問題はありません-以下を参照)、2nd要素から繰り返します。これはmin/maxの唯一の正しい状態です。 1回の反復の後。最初の要素から反復することもできます-最初の要素に対して余分な(不必要な)反復を1回行う以外、違いはありません。

サイズ0のinoutを処理する唯一の健全な方法は単純です。この場合、min/maxは未定義なので、IllegalArgumentExceptionをスローします。

4
Bohemian