본문 바로가기

숨막히는 알고말고/문제 풀이

[Baekjoon] 숫자놀이

👀 문제 설명

문제

79를 영어로 읽되 숫자 단위로 하나씩 읽는다면 "seven nine"이 된다. 80은 마찬가지로 "eight zero"라고 읽는다. 79는 80보다 작지만, 영어로 숫자 하나씩 읽는다면 "eight zero"가 "seven nine"보다 사전순으로 먼저 온다.

문제는 정수 M, N(1 ≤ M, N ≤ 99)이 주어지면 M 이상 N 이하의 정수를 숫자 하나씩 읽었을 때를 기준으로 사전순으로 정렬하여 출력하는 것이다.

 

입력

첫째 줄에 M과 N이 주어진다.

 

출력

M 이상 N 이하의 정수를 문제 조건에 맞게 정렬하여 한 줄에 10개씩 출력한다.

 

예제 입력 1

8 28

 

예제 출력 1

8 9 18 15 14 19 11 17 16 13

12 10 28 25 24 21 27 26 23 22

20

 

✍🏻풀이

숫자들을 ArrayList<Integer>에 넣고, Comparator을 사용해서 정렬해준다.

Comparator 안에서는 숫자들을 영어로 바꾸는 메서드 numToEng를 정의해두고, 그 안에서 String[] eng = { "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine" }; 를 활용해 숫자들을 영어로 바꿔준다.

그리고, compare 메서드에서 영어로 바꾼 값들을 사용해 정렬해주면 된다.

 

코드

package boj;

// 숫자놀이 (https://www.acmicpc.net/problem/1755 )

import java.util.*;
import java.io.*;

public class BOJ_1755 {
	
	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); // 입력받기 위해 BufferedReader 객체 생성
		BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out)); // 출력하기 위해 BUfferedWriter 객체 생성
		StringTokenizer st = new StringTokenizer(br.readLine()); // 공백을 기준으로 입력받아오기 위해 StringTokenizer 객체 생성
		
		int M = Integer.parseInt(st.nextToken()); // 입력받은 M 값을 가져온다.
		int N = Integer.parseInt(st.nextToken()); // 입력받은 N 값을 가져온다.
		
		ArrayList<Integer> nums = new ArrayList<>(); // 정렬할 숫자들을 넣어주기 위한 ArrayList 객체
		
		for (int i = M; i <= N; i++) { // M부터 N까지의 숫자들에 접근
			nums.add(i); // ArrayList nums에 숫자들을 넣는다.
		}
		
		Collections.sort(nums, new Comparator<Integer>() { // Comparator을 사용해서 nums 리스트를 정렬한다.

			@Override
			public int compare(Integer o1, Integer o2) { // 숫자들을 어떤 기준으로 정렬할 것인지 정의하는 메서드
				String o1ToEng = numToEng(Integer.toString(o1)); // o1 숫자를 영어로 읽은 값을 가져온다.
				String o2ToEng = numToEng(Integer.toString(o2)); // o2 숫자를 영어로 읽은 값을 가져온다.
				
				return o1ToEng.compareTo(o2ToEng); // 영단어 사전순으로 정렬한다.
			}
			
			// numToEng 메서드는 숫자들을 영어로 읽을 때의 String 값을 반환한다.
			private String numToEng(String num) { // num이라는 숫자(String으로 바꾼 형태)를 매개변수로 받아와서, 영어로 읽었을 때의 String 값을 반환한다.
				String[] eng = { "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine" }; // 각 숫자들을 영어로 바꾼걸 저장하는 배열 (eng[0]은 숫자 0을 영어로 읽을 떄의 값을 저장한다.)
				
				String numToEng = ""; // num 숫자를 영어로 읽을 때의 값을 저장
				for (int idx = 0; idx < num.length(); idx++) { // num  숫자의 각 자릿수에 접근한다. (ex. num이 "13"이라면, 1과 3에 각각 접근)
					numToEng += eng[num.charAt(idx) - '0']; // eng 배열을 사용해 각 자릿수의 숫자를 영어로 읽을 때의 값을 가져와서 numToEng에 붙여준다.
					numToEng += " "; // 각 자릿수 사이에 공백 추가 (ex. 80인 경우, eightzero가 아니라 eight zero로 만들어주기 위함)
				}
				
				return numToEng; // 영어로 변환한 값을 반환한다.
			}

		});
		
		// 출력
		for (int i = 0; i < nums.size(); i++) { // nums 리스트에 하나씩 접근한다.
			// 한 줄에 10개씩 출력해야 한다. 한 줄의 가장 오른쪽에 오는 인덱스는 10으로 나눴을 때 나머지가 9인 인덱스이다. (인덱스가 0부터 시작하므로)
			if (i % 10 == 9) { // 한 줄의 가장 오른쪽에 오는 인덱스라면 줄바꿈
				bw.write(nums.get(i) + "\n");
			}
			else { // 한 줄의 가장 오른쪽에 오는 경우가 아니라면 공백을 더해준다.
				bw.write(nums.get(i) + " ");
			}
		}
		
		bw.flush(); // 출력 스트림에 쌓인 애들을 내보내준다.
		bw.close(); // BufferedWriter를 다 썼다면 close 해준다.
	}
	
}

'숨막히는 알고말고 > 문제 풀이' 카테고리의 다른 글

[Baekjoo] 나무 재테크  (0) 2021.09.29
[Baekjoon] 이분 그래프  (0) 2021.09.27
[Baekjoon] 동전 2  (0) 2021.09.26
[Baekjoon] 게리맨더링 2  (0) 2021.09.25
[Baekjoon] AC  (0) 2021.09.25