21.05.22 기록
-
백준 알고리즘 1157 풀이 완료
- 내가 푼 1157 풀이 (메모리 22.1MB, 시간 316ms로 통과)
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.nio.charset.StandardCharsets; import java.util.Locale; public class B1157 { public static void main(String[] args) { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); int[] check = new int[26]; try { byte[] word = br.readLine().toLowerCase(Locale.ROOT).getBytes(StandardCharsets.UTF_8); for(int i = 0; i < word.length; i++) { check[word[i]-97]++; } int max = 0; for(int i = 0; i < check.length; i++) { if(check[i] > max) max = check[i]; } int cnt = 0; for(int i = 0; i < check.length; i++) { if(check[i] == max) cnt++; } if(cnt > 1) { System.out.println("?"); return; } for(int i = 0; i < check.length; i++) { if(check[i] == max) { System.out.println((char) (i+65)); break; } } } catch (IOException e) { e.printStackTrace(); } } }- 먼저 입력받은 단어를
toLowerCase를 사용하여 소문자로 모두 바꾼 후getBytes를 통해 byte 배열로 저장했다. - byte 배열의 길이만큼 for문을 돌면서 (byte 배열의 각 값 - 97)한 값을 int 배열의 인덱스로 사용하였다.
- a의 아스키코드 값이 97이기 때문에 97을 빼주어 a부터 시작하는 제로 인덱스를 만들어준 것이다.
- 두번째 for문에서는 int 배열을 순회하면서 요소 중 최댓값을 구했다. (→ 문자 중 가장 많이 등장한 문자를 구한 것)
- 세번째 for문에서는 int 배열을 다시 순회하면서 cnt 변수로 최댓값의 중복을 검사했다. (1이면 최댓값이 한 개, 2이상이면 최댓값을 가진 요소가 2개 이상)
- cnt 값이 2 이상이면 물음표를 출력한 후 함수가 종료되고, 그렇지 않으면 네번째 for문을 돌면서 가장 많이 등장한 문자를 대문자로 출력한다.
- 내가 푼 1157 풀이 (메모리 22.1MB, 시간 316ms로 통과)
-
스스로 풀고도 어렵게 느껴져서 다른 풀이를 찾아보았다.
-
다른 풀이(1):
toLowerCase대신 for문 안에서charAt()을 사용하고,getBytes대신 String을 사용한다.(메모리 19.9MB, 시간 280ms로 통과)
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class B1157 {
public static void main(String[] args) {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int[] check = new int[26];
try {
String word = br.readLine();
for(int i = 0; i < word.length(); i++) {
if('a' <= word.charAt(i) && word.charAt(i) <= 'z') {
check[word.charAt(i) - 97]++;
} else {
check[word.charAt(i) - 65]++;
}
}
int max = -1;
char ch = '?';
for(int i = 0; i < check.length; i++) {
if(check[i] > max) {
max = check[i];
ch = (char) (i+65);
} else if(check[i] == max){
ch = '?';
}
}
System.out.println(ch);
} catch (IOException e) {
e.printStackTrace();
}
}
}
- 첫번째 for문에서 문자가 소문자일 때에는 -97을, 대문자일 때에는 -65한 값을 int형 배열의 인덱스로 사용한다.
- 두번째 for문에서는 if-else if문을 사용하여 max 값보다 클 때에는 문자의 대문자를, max 값과 같으면 ?를 출력하도록 한다.
- 다른 풀이(2): BufferedReader 대신 System.in.read()로 입력을 받는다.(메모리 14.2MB, 시간 160ms로 통과)
import java.io.IOException;
public class B1157 {
public static void main(String[] args) {
int[] check = new int[26];
try {
int b = System.in.read();
while(b > 64) { //입력 받은 값의 아스키 코드가 65(A) 이상일 때
if(b < 91) { //대문자일 때
check[b - 65]++;
} else { //소문자일 때
check[b - 97]++;
}
b = System.in.read(); //다음 문자 입력 받기
}
int max = -1;
int ch = -2; // ?의 아스키코드 값은 63이다.
for(int i = 0; i < check.length; i++) {
if(check[i] > max) {
max = check[i];
ch = i;
} else if(check[i] == max) {
ch = -2;
}
}
System.out.println((char) (ch+65));
} catch (IOException e) {
e.printStackTrace();
}
}
}