【Java】複数の標準入力から最大値と最小値を取得する方法

エンジニア歴２カ月のyoshidaです。
今回は、某学習サイトでぶつかった「複数の標準入力から最大値と最小値を得る方法」について学んだことをご紹介、、

ご紹介するのは下記３つの書き方

>1. if文
>2. sort()
>3. Math.max/Math.minメソッド

個人的なおすすめはif文、、。if文ってすごい！

## 例題
>標準入力から5つの整数a_1 a_2 ... a_Nが与えられます。
>各整数（a_1 a_2 ... a_N）は0以上100以下です。
>入力された整数から、最大値と最小値を出力してください。

**入力**
```
4 3 5 1 2
```

**期待する出力**
```
最大値：5 最小値：1
```

## if文を使って最大値・最小値を取得する
**難易度：★☆☆**
一番シンプルで、原理さえわかってしまえばすぐに書けるはず、、
sortとは、、メソッドとは、、という人におすすめ。ぜひ原点に立ち返ってif文のすごさを味わいましょう((

:::note info
**おすすめPoint**
・とてもシンプル
・2つの入力はもちろん、3つ以上、100個以上の標準入力でも大丈夫
:::

#### サンプルコード（解答①）
```ruby
import java.util.*;

public class Main{
	public static void main(String[] args){
		Scanner sc = new Scanner(System.in);

        int answerMax = 0;
		int answerMin = 101;
  
		for(int i = 0; i < 5; i++){
			int inputNum = sc.nextInt();
            if(inputNum > answerMax){
                answerMax = inputNum;
			}
			if(inputNum < answerMin){
				answerMin = inputNum;
			}
		}
  
		System.out.println("最大値：" + answerMax + " 最小値：" + answerMin);
	}
}

```

#### 解説
 for文1回目：
 anserMaxは初期値として0を与えられているので、初めに入力される値4と比較するとinputNum > answerMax。
 よって、answerMaxは4になる。
 
 ```ruby
 if(inputNum > answerMax){
    answerMax = inputNum;
}
```
for文2回目：
次に入力される値3。
先ほどの流れからanserMaxは4になっているので、比較するとinputNum < answerMax。
if文の条件に当てはまらないため、answerMaxは4のまま。

こんな流れで、for文が5回実行されたときanswerMaxは最大値の5になっている。
最小値は比較演算子を逆にして、小さい場合に置換って感じ。

**つまり、、**
 入力値(inputNum)を変数(answerMax, answerMin)をfor文で設定した回数分比較する。
 今回の場合、標準入力から与えられるのは5回なので5回分sc.nextInt()で整数を取得し、変数(answerMax, answerMin)と比較して大小を比べていく。
 

## sort()を使って最大値・最小値を取得する
**難易度：★★☆**
ArrayListやsortに慣れるには最適な難易度。

:::note info
**おすすめPoint**
・sortやArrayListの勉強になる
・2つの入力はもちろん、3つ以上、100個以上の標準入力でも大丈夫
:::

#### サンプルコード（解答②）
```ruby
import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        
        //ArrayList（inputNums）の作成
        List<Integer> inputNums = new ArrayList<Integer>();

        //inputNumsに入力値（input）をすべて格納
        for(int i = 0; i < 5; i++){
            int inputNum = sc.nextInt();
            inputNums.add(inputNum);
        }

        //arrayを昇順に並び替え
        Collections.sort(inputNums);
        
        //出力
        System.out.println("最大値：" + inputNums.get(4) + " 最小値：" + inputNums.get(0));        
    }
}

```

#### 解説
```ruby
Collections.sort(inputNums);
```
でinputNumsを昇順に並び替えるところがPoint。
>**Collections.sort(inputNums);** する前のinputNumsの中身
>`4 3 5 1 2`
>**Collections.sort(inputNums);** した後のinputNumsの中身
>`1 2 3 4 5`

 昇順なので、並べ替えた後のリストの一番最初（inputNums.get(0)）には最小値、リストの一番最後（inputNums.get(4))には最大値が入っている。
 
## Math.max()/Math.min()を使って最大値・最小値を取得する
**難易度：★★☆**
３つ以上の数字から最大値/最小値を取得したい場合は、あまりお勧めしない。

:::note info
**おすすめPoint**
・配列とMath.max()/Math.min()の勉強になる
・2つの入力はもちろん、3つ以上、100個以上の標準入力でも大丈夫
:::

#### サンプルコード（解答③）
```ruby
import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        
        //5つの要素を持つことができる配列を用意
        int[] inputNums = new int[5];

        //標準入力を取得して配列に格納
        for (int i = 0; i < 5; i++) {
            inputNums[i] = scanner.nextInt();
        }

        //Math.max()・Math.max()を使用して配列から最大値・最小値を求める
        int answerMax = inputNums[0];
        int answerMin = inputNums[0];
        for (int i = 1; i < 5; i++) {
            answerMax = Math.max(answerMax, inputNums[i]);
            answerMin = Math.min(answerMin, inputNums[i]);
        }

        //出力
        System.out.println("最大値：" + answerMax + " 最小値：" + answerMin);
    }
}
```

#### 解説
**Math.maxメソッドの使い方**
引数を2つ指定し、大きい方を返すメソッド。
```ruby
max = Math.max(10, 100);
```
このとき、maxは100

**Math.minメソッドの使い方**
引数を2つ指定し、小さい方を返すメソッド。
```ruby
min = Math.min(10, 100);
```
このとき、minは10

--

2つの大小しか比較することができないので、初めに配列を用意してからfor文で1つずつ比較しなければならない。
answerMaxとanswerMinには、それぞれ比較して得られた大きい方と小さい方になるため、すべて比較し終わったときのanswerMaxとanswerMinは最大値と最小値になる。

#### Math.max()/Math.min()を使用した脳筋コード（解答④）

```ruby
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);

        //5つの要素を持つことができる配列を用意
        int[] inputNums = new int[5];

        //標準入力を取得して配列に格納
        for (int i = 0; i < 5; i++) {
            inputNums[i] = scanner.nextInt();
        }

        //Math.max()を使用して配列から最大値を求める
        int answerMax = Math.max(inputNums[0], Math.max(inputNums[1], Math.max(inputNums[2], Math.max(inputNums[3], inputNums[4]))));

        //Math.min()を使用して配列から最大値を求める
        int answerMin = Math.min(inputNums[0], Math.min(inputNums[1], Math.min(inputNums[2], Math.min(inputNums[3], inputNums[4]))));

        // 出力
        System.out.println("最大値：" + answerMax + " 最小値：" + answerMin);
    }
}
```
:::note warn
注意
ネストの勉強になるが、あまりにも脳筋なのでお勧めしません((
:::

## おわりに
初学者から初学者に向けて、かなり詳細にご紹介できたのではないだろうか、、。

今回ご紹介したように、1つの問題に対して期待する出力を得られるコードは様々。
今後はその中から、良いコードを選んでいく必要があるんだろうなと想像中、、。

最近はまっているのは、**保守性の観点**からみてどうすべきなのか。
良いエンジニアになるため、日々精進していきたい所存。