[Java] 백준 1157번

Input-1
Mississipi
Output-1
?
Input-2
zZa
Output-2
Z
Input-3
baaa
Output-3
A
문제 풀이
알파벳 대소문자로된 단어가 주어지면 해당 단어의 범위는 아래와 같다.
- a~z 또는 A~Z
이 문제의 핵심은 문자의 인코딩 값을 다루는 것이다.
먼저 각 알파벳 별로 사용된 빈도수를 측정하기 위한 배열을 선언한다.
1
int[] alph_list = new int[26]; // 알파벳은 총 26개
그리고 단어를 입력받는데 대소문자는 구분하지 않으니 대문자이거나 소문자이거나 같은 위치의 배열 값을 증가시켜야 한다.
- 입력 단어가 C든 c든 alph_list에서는 c의 자리인 2번 원소 값을 증가시켜야 한다.
어떻게 대소문자 구분없이 같은 원소에 접근할 수 있을까?
주어진 단어를 아스키코드로 변환하여 접근해야 한다.
- 소문자인 a~z는 97~122이고 대문자인 A~Z는 65~90이다.
만약 대문자 C를 입력받았다면 C를 아스키코드로 변환하면 67이기에 65를 빼면 2이다. 또한 소문자 c를 입력받았다면 c를 아스키코드로 변환하면 99이고 97을 빼면 2가 된다. 2는 alph_list에서 2 원소값을 담당하고 있지 않은가..!
그렇게 주어진 단어를 아스키 코드로 변환하여 대문자면 65, 소문자면 97를 뺀 값으로 alph_list 배열의 원소로 접근할 수 있다.
1
2
3
4
5
6
7
String str = br.readLine(); // 입력받은 단어
// 1. 대문자일 경우 주어진 단어에서 65를 뺀 값으로 원소에 접근하여 증가시킨다.
// 2. 소문자일 경우 97을 뺀 값으로 원소에 접근하여 증가시킨다.
for (int i=0; i<str.length(); i++) {
if(str.charAt(i)>=65 && str.charAt(i)<=90) alph_list[str.charAt(i)-65] += 1;
else alph_list[str.charAt(i)-97] += 1;
}
주어진 단어를 통해 알파벳 배열에서의 사용 빈도수를 측정했으니 해당 배열들의 원소값을 비교하여 가장 큰 값을 가진 원소를 찾아야 한다. 기존에 알고 있던 배열에서의 최댓값 구하는 로직을 그대로 적용하였다.
가장 큰 값을 가진 원소의 인덱스를 찾으면 대문자로 출력해야 하니 해당 인덱스에 65를 더하고 char형으로 파싱하여 대문자로 출력할 수 있다.
여기서 만약 가장 큰 값(max)이 2개 이상이라면 ?를 출력할 수 있도록 작성하였다.
1
2
3
4
5
6
7
8
9
10
int max = 0;
char result = '?';
for (int j=0; j<alph_list.length; j++) {
if (max < alph_list[j]) {
max = alph_list[j];
result = (char) (j+65);
}
else if (max == alph_list[j]) result = '?';
}
bw.write(result + "\n");
char형으로 파싱하며 왜 char형은 홑 따옴표를 쓰는지 궁금해서 찾아보았다.
문자형 char란?
- 하나의 문자를 저장하기 위한 변수를 선언할 때 사용된다.
- 말 그대로 하나의 문자만 저장할 수 있다.
- 주로 문자, 유니코드, 아스키코드를 나타낼 수 있다.
- 꼭 홑 따옴표로 감싸주어야 한다. ex) char c = ‘a’;
작성코드
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import java.io.*;
class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
int[] alph_list = new int[26];
String str = br.readLine();
for (int i=0; i<str.length(); i++) {
if(str.charAt(i)>=65 && str.charAt(i)<=90) alph_list[str.charAt(i)-65] += 1;
else alph_list[str.charAt(i)-97] += 1;
}
int max = 0;
char result = '?';
for (int j=0; j<alph_list.length; j++) {
if (max < alph_list[j]) {
max = alph_list[j];
result = (char) (j+65);
}
else if (max == alph_list[j]) result = '?';
}
bw.write(result + "\n");
bw.flush();
bw.close();
br.close();
}
}
회고
- 문자의 인코딩 값에 대해 제대로 파악하지 못해 많은 시간을 들여 문제를 풀게 되었다.
- 문자형 char를 활용함으로써 훨씬 안정적이고 좋은 성능을 낼 수 있다고 알게 되었다.