문제
N
개의 정수가 주어진다. 이때, 최솟값과 최댓값을 구하는 프로그램을 작성하시오.
입력
첫째 줄에 정수의 개수 N
(1 ≤ N ≤ 1,000,000)
이 주어진다. 둘째 줄에는 N
개의 정수를 공백으로 구분해서 주어진다. 모든 정수는 -1,000,000
보다 크거나 같고, 1,000,000
보다 작거나 같은 정수이다.
출력
첫째 줄에 주어진 정수 N개의 최솟값과 최댓값을 공백으로 구분해 출력한다.
문제 풀이
맨 처음 푼 코드는 다음과 같다.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int n = Integer.parseInt(br.readLine());
ArrayList<Integer> list = new ArrayList<>();
int max = 0;
int min = 0;
for (int i = 0; i < n; i++) {
list.add(Integer.parseInt(br.readLine()));
}
System.out.println(list);
for (int i = 0; i < list.size(); i++) {
max = Math.max(max, list.get(i));
min = Math.min(min, list.get(i));
}
System.out.println(max + " " + min);
br.close(); // 사용 후 BufferedReader 닫기
}
}
max
와 min
을 각각 0
으로 초기화한다음,for
문을 이용해서 입력을 받는다.
입력 받은 수들을 list
에 저장하고, list
를 순회하면서 최댓값과 최소값을 구하는 식으로 구현을 했었다.
하지만 이 코드에는 치명적인 문제점이 있었다.
문제에서는 "둘째 줄에는 N
개의 정수를 공백으로 구분해서 주어진다"라고 되어 있지만 코드에서는 각 정수를 별도의 줄에서 읽고 있다.max = 0
, min = 0
으로 초기화하면 모든 입력값이 0
보다 작으면 최댓값이 잘못되고, 모든 입력값이 0
보다 크면 최솟값이 잘못된다.
int max = Integer.MIN_VALUE; // -2,147,483,648로 초기화
int min = Integer.MAX_VALUE; // 2,147,483,647로 초기화
그래서 최대한 작은 값과 최대한 큰 값으로 초기화를 한다.
수정사항을 반영한 코드는 아래와 같다.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int n = Integer.parseInt(br.readLine());
StringTokenizer st = new StringTokenizer(br.readLine(), " ");
int max = Integer.MIN_VALUE; // 최솟값으로 초기화
int min = Integer.MAX_VALUE; // 최댓값으로 초기화
for (int i = 0; i < n; i++) {
int num = Integer.parseInt(st.nextToken());
max = Math.max(max, num);
min = Math.min(min, num);
}
System.out.println(min + " " + max);
br.close();
}
}
간단한 코드 설명은 아래와 같다.
int n = Integer.parseInt(br.readLine());
br.readLine()
: 한 줄을 읽어온다(첫 번째 줄에 있는 정수 개수 N
).Integer.parseInt()
: 읽어온 문자열을 정수로 변환한다.
StringTokenizer st = new StringTokenizer(br.readLine(), " ");
두 번째 줄을 읽어온다(N
개의 정수가 공백으로 구분되어 있음).StringTokenizer
를 사용해 이 줄을 공백(" ") 기준으로 토큰(각 숫자)으로 나눈다.
int max = Integer.MIN_VALUE; // 최솟값으로 초기화
int min = Integer.MAX_VALUE; // 최댓값으로 초기화
max
: 최댓값을 저장할 변수. 어떤 입력된 정수보다도 작은 값(-2147483648
)으로 초기화한다.min
: 최솟값을 저장할 변수. 어떤 입력된 정수보다도 큰 값(2147483647
)으로 초기화한다.
for (int i = 0; i < n; i++) {
int num = Integer.parseInt(st.nextToken());
N
번 반복하면서 각 토큰(숫자)을 하나씩 가져온다.st.nextToken()
: 다음 토큰(공백으로 구분된 다음 숫자)을 가져온다.
가져온 토큰을 정수로 변환하여 num
에 저장한다.
max = Math.max(max, num);
min = Math.min(min, num);
}
Math.max(max, num)
: max
와 num
중 더 큰 값을 max
에 저장한다.Math.min(min, num)
: min
과 num
중 더 작은 값을 min
에 저장한다.
이렇게 해서 모든 숫자를 순회하면서 최댓값과 최솟값을 계속 업데이트한다.
이번 문제도 StringTokenizer
를 사용하여 해결하였다.
이번 문제에서 궁금했던건 for
문 안에 있는 StringTokenizer
에 n
이 없어도 순회가 가능한 점이었다.StringTokenizer
는 내부적으로 위치를 기억하고 있어서 추가적인 인덱스 변수 없이도 모든 토큰을 순차적으로 처리할 수 있다고 한다. 이것이 StringTokenizer
를 사용하는 장점이라고 한다.
앞으로 문제를 풀 때에는 StringTokenizer
사용법을 더 자세히 공부해봐야겠다.
'PROBLEM SOLVING' 카테고리의 다른 글
[백준] 새싹 (0) | 2025.04.22 |
---|---|
[백준] 소수 찾기 (0) | 2025.04.22 |
[백준] 알파벳 찾기 (0) | 2025.04.21 |
[백준] N 찍기 (1) | 2025.04.21 |
[백준] 단어의 개수 (0) | 2025.04.21 |