Integer.MAX_VALUE
とInteger.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_VALUE
とInteger.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);
}
}
では、比較においてInteger.MIN_VALUEとInteger.MIN_VALUEはどのような目的に役立つのでしょうか?
しかし、この方法については、Integer.MAX_VALUEとInteger.MIN_VALUEの目的がわかりません。
smallest
をInteger.MAX_VALUE
に設定し、largest
をInteger.MIN_VALUE
に設定して開始することで、smallest
およびlargest
にまだ値がない特別なケースについて後で心配する必要がなくなります。調べているデータの最初の値が10
である場合、numbers[i]<smallest
はtrueになり(10
は<
Integer.MAX_VALUE
であるため)、smallest
を10
に更新します。同様に、numbers[i]>largest
は10
>
であり、true
を更新するため、Integer.MIN_VALUE
はlargest
になります。等々。
もちろん、これを行うときは、調べているデータに少なくとも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
}
}
修正するには、次のいずれかを実行します。
else
を使用しない、または
最初の要素に等しい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
}
}
任意の値(たとえばint smallest = 9999, largest = 0
)で変数を初期化する代わりに、その数値型(つまりint smallest = Integer.MAX_VALUE, largest = Integer.MIN_VALUE
)で表現できる最大値と最小値で変数を初期化する方が安全です。
整数配列にInteger.MAX_VALUE
より大きくInteger.MIN_VALUE
より小さい値を含めることはできないため、コードはすべてのEdgeケースで機能します。
最小/最大値を極端に反対に初期化することで、入力の値のエッジのケースを回避します:実際には、最小/最大のいずれかがそれらの値の1つです(入力がこれらの値の1つのみで構成される場合) )、または正しい最小/最大が見つかります。
プリミティブ型mustには値があることに注意してください。オブジェクト(つまりInteger
)を使用した場合、値をnull
に初期化し、最初の比較のためにその特殊なケースを処理できますが、余分な(不要な)コードが作成されます。ただし、これらの値を使用することで、ループコードは最初の比較のエッジケースを心配する必要がありません。
別の代替方法は、両方の初期値を入力配列の最初の値に設定し(問題はありません-以下を参照)、2nd要素から繰り返します。これはmin/maxの唯一の正しい状態です。 1回の反復の後。最初の要素から反復することもできます-最初の要素に対して余分な(不必要な)反復を1回行う以外、違いはありません。
サイズ0のinoutを処理する唯一の健全な方法は単純です。この場合、min/maxは未定義なので、IllegalArgumentException
をスローします。