[백준] 10817번 : 세 수 - JAVA [자바]
https://www.acmicpc.net/problem/10817
10817번: 세 수
첫째 줄에 세 정수 A, B, C가 공백으로 구분되어 주어진다. (1 ≤ A, B, C ≤ 100)
www.acmicpc.net
-
문제
매우 간단한 문제다!
※ 주의할 점
- 입력은 공백으로 구분되어 주어진다
- 두 번째로 큰 정수를 출력해야 한다.
- 4가지 방법을 보여주고자 한다.
사실 이 문제는 세 개의 수만 주어지므로 배열에 각 원소를 넣고 정렬만 해준 뒤 두 번째 원소만 출력해주면 끝난다.
그래도 if문 분류이니...
20.02.13 ) 백준에서 if 문 카테고리에서 실습 1로 변경되었다.
20.10.25 ) 실습 1 카테고리가 없어져 기타 문제로 카테고리를 옮겼다.
- 정렬 메소드를 사용하지 않고 직접 배열을 정렬하여 쓰는 방법 (Scanner)
- 배열을 쓰지 않고 쓰는 방법
- 성능 개선 코드
- 알고리즘
배열에 담아 정렬하는 알고리즘을 설명하려 한다.
사실 Arrays.sort() 메소드를 이용하면 알아서 정렬해주지만 간단하게나마 직접 정렬하는 알고리즘을 작성해보는 것이 정렬 메커니즘을 아는데 더 수월 할 것이다.
(오름차순으로 정렬할 것이다.)
먼저 배열 원소 간의 교체 방법이다.
1. temp 라는 임시 변수를 선언한다.
2. 두 번째 index 의 원소를 temp 에 담는다. ( temp = arr[1] )
3. 배열의 두 번째 index 에 첫 번째 index 원소 값을 넣어준다. ( arr[1] = arr[0] )
4. temp 에 담겨있던 값을 첫 번째 index 에 넣어준다. ( arr[0] = temp )
이런 원리다.
그럼 전체 정렬(오름차순)을 하려면 어떻게 하냐
i 번째 원소와 i+n 번째 원소를 비교한 뒤 i 번째 원소가 더 클 경우 i+n 번째 원소와 교체해준다.
다음 아래 그림을 보면 이해가 빠를 것이다.
즉 i 번째 원소와 교체 i 번째 뒤의 원소들을 비교하면서 i 번째 원소 > i+n 번째 원소 일 경우 서로 원소를 교체해준다.
(포토샵을 잘 못 다뤄서 퀄리티가 좀 떨어지더라도 양해 부탁드린다....)
자세한 코드는 풀이에서 보자
- 풀이
- 방법 1
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int arr[] = {in.nextInt(), in.nextInt(), in.nextInt()};
in.close();
/*
가장 최후의 비교는 마지막 -1 번째 원소와 가장 마지막 원소이므로
i 는 배열 길이-1 까지만 반복해주면 된다.
*/
for(int i=0; i<arr.length-1;i++) {
for(int j =i+1; j<arr.length;j++) {
if(arr[i]>arr[j]) {
int temp = arr[i];
arr[i]=arr[j];
arr[j]=temp;
}
}
}
System.out.println(arr[1]);
}
}
가장 기초적인 방법일 것이다.
물론 저렇게 복잡하게 말고 아래와 같이 java.util 패키지의 Arrays 클래스를 import 해주고
그 안에 있는 sort() 메소드를 써주어 간단하게 풀리긴 한다..
다만 if 문의 의미가 있을까..?
import java.util.Scanner;
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int arr[] = {in.nextInt(), in.nextInt(), in.nextInt()};
in.close();
Arrays.sort(arr); //정렬 메소드 (기본이 오름차순이다.)
System.out.println(arr[1]);
}
}
- 방법 2
배열을 사용하지 않고 쓸 수도 있다. 즉 각각의 변수끼리 비교한 뒤 출력해주면 된다.
즉 세 수 중 나올 수 있는 모든 가능성을 조건문으로 처리해버리는 무식한 방법이다.
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int a = in.nextInt();
int b = in.nextInt();
int c = in.nextInt();
in.close();
if (a >= b) {
if (a >= c) { // a가 가장 크거나 모두 같을 경우
if (b >= c)
System.out.println(b);
else
System.out.println(c);
} else
System.out.println(a);
} else {
if (c <= b) { // b가 가장 큰 수일 경우
if (c <= a)
System.out.println(a);
else
System.out.println(c);
} else
System.out.println(b);
}
}
}
- 성능 개선 코드
필자가 제출했던 코드인데 BufferedReader 을 쓰는 방식이다.
readLine() 을 통해 입력받아 연산하는 방법을 설명할 것이다.
앞서 말했듯이 readLine() 은 한 행을 전부 읽기 때문에 공백 단위로 입력해 준 문자열을 공백 단위로 분리해주어야 문제를 풀 수 있을 것이다.
문자열 분리 방법으로는 split 보다 StringTokenizer가 성능이 좋으니 StringTokenizer을 사용할 것이다.
그리고 반드시 자료형 타입을 잘 보아야 한다.
st.nextToken() 은 문자열을 반환하니 Integer.parseInt()로 int 형으로 변환시켜준다.
아래 코드가 필자가 제출했던 코드다.
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
import java.util.StringTokenizer;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine(), " ");
int[] arr = new int[3];
for (int i = 0; i < 3; i++) {
arr[i] = Integer.parseInt(st.nextToken());
}
for (int i = 0; i < 2; i++) {
for (int j = i + 1; j < 3; j++) {
if (arr[i] > arr[j]) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
}
System.out.println(arr[1]);
}
}
필자가 제출했던 코드는 아닌데 배열을 쓰지 않고 했던 방법을 이용하여 아래와 같이 쓸 수도 있다는 점을 알아두었으면 한다.
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
import java.util.StringTokenizer;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String str = br.readLine();
StringTokenizer st = new StringTokenizer(str, " ");
int a = Integer.parseInt(st.nextToken());
int b = Integer.parseInt(st.nextToken());
int c = Integer.parseInt(st.nextToken());
if (a >= b) {
if (a >= c) {
// a가 가장 크거나 모두 같을 경우
if (b >= c)
System.out.println(b);
else
System.out.println(c);
} else
System.out.println(a);
} else {
if (c <= b) { // b가 가장 큰 수일 경우
if (c <= a)
System.out.println(a);
else
System.out.println(c);
} else
System.out.println(b);
}
}
}
이렇게 다양한 방법이 있으니 여러분들이 하나씩 보시고 마음에 드는 코드를 사용하면 될 거 같다.
- 성능 차이
위에서부터 순서대로
채점 번호 : 17665239 - BufferedReader + Arrays.sort
채점 번호 : 17665228 - BufferedReader + if ( 배열 x )
채점 번호 : 17665218 - BufferedReader + 배열 정렬
채점 번호 : 17665215 - Scanner + if ( 배열 x )
채점 번호 : 17665209 - Scanner + Arrays.sort
채점 번호 : 17665203 - Scanner + 배열 정렬
시간을 보면 BufferedReader 와 Scanner 의 성능 차이가 확연하게 나는 것을 볼 수가 있다.
정렬 간의 시간 차이는 거의 없는 것 같다. 다만 같은 조건에서 정렬할 경우 Arrays 클래스를 불러오는데 아주 미세하게 시간 차이가 날 수도 있겠다만 (유의미한 시간일지는 잘 모르겠다..)
- 정리
if 조건문 마지막에서는 다양한 접근 방법이 있을 수 있음을 알려주려고 노력했다.
물론 쉽고 간편한 방법들이 존재하지만 그래도 알고리즘을 분석하고 풀어내는데 초점을 두는만큼 직접 배열을 정렬해보기도 하고 변수들의 가능성을 모두 조건문으로 처리하여 풀어낼 수도 있다는 것을 알았으면 한다.
'JAVA - 백준 [BAEK JOON] > 기타 문제' 카테고리의 다른 글
[백준] 5543번 : 상근날드 - JAVA [자바] (0) | 2020.03.04 |
---|---|
[백준] 2577번 : 숫자의 개수 - JAVA [자바] (36) | 2020.02.28 |
[백준] 2742번 : 기찍 N - JAVA [자바] (6) | 2020.02.18 |
[백준] 2741번 : N 찍기 - JAVA [자바] (11) | 2020.02.18 |
[백준] 10718번 : We love kriii - JAVA [자바] (4) | 2020.02.01 |