https://www.acmicpc.net/problem/2941
❓
금방 풀 수 있을 거라 생각했는데 자잘한 문제에 막혀서 몇 시간을 고생했다.
처음엔 [ic]System.in.read()[/ic]로 한 글자씩 입력 받도록 코드를 작성했는데,
그렇게 하니 \r, \n이 들어오는 경우도 생각해야 해서 코드가 난잡해져 [ic]BufferedReader[/ic]를 이용해 풀어보려 했다.
그렇게 이클립스로 코드를 작성하고 테스트 해보니 잘 돌아가는 것 같아서 백준에 제출했더니 오답...
❗
결국 구글링을 통해 다른 사람들의 코드를 본 후 풀었다.
✨ 참고
풀이(오답) (+ 23.09.05)
- BufferedReader로 한 줄 입력 받기
- 문자열 길이만큼 for문을 반복해서 한 글자씩 확인 후 단어 개수 증감 여부 체크
- 표에 나와있는 알파벳으로 시작하는 경우 for문 순서 건너뛰기
사실 지금도 어디가 틀렸는지 잘 모르겠다.
꾸준히 문제 풀어보고 나중에 다시 확인했을 땐 깨닫지 않을까 싶어 일단 코드를 올려본다.
이유 알아냄
case 코드 내 else if문에서 다음 문자가 case 변수와 같을 경우만 처리했기 때문이었음
표에 나와있는 문자의 첫 알파벳인 경우도 다 처리해야 한다.
- d로 시작하는 경우 다음 문자가 z인 경우는 따로 처리 해야함.
- StringIndexOutOfBounds 오류가 발생할 수 있기 때문에 문자열이 dz로 끝나는 경우 인덱스의 크기를 더 키우면 안 됨
오류난 코드
더보기
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class CroatiaAlphabet2941 {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String word = br.readLine();
char alphabet;
int count = 0;
for (int i=0; i<word.length(); i++) {
alphabet = word.charAt(i);
if (i == word.length()-1) {
count++;
break;
}
switch(alphabet) {
case 'c':
i++;
alphabet = word.charAt(i);
if (alphabet == '=' || alphabet == '-')
count++;
else if (alphabet == 'c') {
count++;
i--;
}
else
count += 2;
break;
case 'd':
i++;
alphabet = word.charAt(i);
if (alphabet == '-')
count++;
else if (alphabet == 'd') {
count++;
i--;
}
else if (alphabet == 'z') {
i++;
alphabet = word.charAt(i);
if (alphabet == '=')
count++;
else if (alphabet == 'd') {
count += 2;
i--;
}
else
count += 3;
}
else
count += 2;
break;
case 'l': case 'n':
i++;
alphabet = word.charAt(i);
if (alphabet == 'j')
count++;
else if (alphabet == 'l' || alphabet == 'n') {
count++;
i--;
}
else
count += 2;
break;
case 's': case 'z':
i++;
alphabet = word.charAt(i);
if (alphabet == '=')
count++;
else if (alphabet == 's' || alphabet == 'z') {
count++;
i--;
}
else
count += 2;
break;
default:
count++;
}
}
System.out.println(count);
}
}
수정한 코드
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String word = br.readLine();
char alphabet;
int count = 0;
for (int i=0; i<word.length(); i++) {
alphabet = word.charAt(i);
if (i == word.length()-1) {
count++;
break;
}
switch(alphabet) {
case 'c':
i++;
alphabet = word.charAt(i);
if (alphabet == '=' || alphabet == '-')
count++;
else if (alphabet == 'c' || alphabet == 'd' || alphabet == 'n'
|| alphabet == 'l' || alphabet == 's' || alphabet == 'z') {
count++;
i--;
}
else
count += 2;
break;
case 'd':
i++;
alphabet = word.charAt(i);
if (alphabet == '-')
count++;
else if (alphabet == 'c' || alphabet == 'd' || alphabet == 'n'
|| alphabet == 'l' || alphabet == 's') {
count++;
i--;
}
else if (alphabet == 'z') { // 다음 문자 z인 경우 따로 처리
if (i == word.length()-1) { // StringIndexOutOfBounds 방지
count += 2;
break;
}
i++;
alphabet = word.charAt(i);
if (alphabet == '=')
count++;
else if (alphabet == 'c' || alphabet == 'd' || alphabet == 'n'
|| alphabet == 'l' || alphabet == 's' || alphabet == 'z') {
count += 2;
i--;
}
else
count += 3;
}
else
count += 2;
break;
case 'l': case 'n':
i++;
alphabet = word.charAt(i);
if (alphabet == 'j')
count++;
else if (alphabet == 'c' || alphabet == 'd' || alphabet == 'n'
|| alphabet == 'l' || alphabet == 's' || alphabet == 'z') {
count++;
i--;
}
else
count += 2;
break;
case 's': case 'z':
i++;
alphabet = word.charAt(i);
if (alphabet == '=')
count++;
else if (alphabet == 'c' || alphabet == 'd' || alphabet == 'n'
|| alphabet == 'l' || alphabet == 's' || alphabet == 'z') {
count++;
i--;
}
else
count += 2;
break;
default:
count++;
}
}
System.out.println(count);
}
}
풀이(정답)
위 풀이와 방식은 동일하지만 차이점이 있다.
위에선 표에 나와있는 알파벳으로 시작하는 경우 무조건 순서를 건너뛰었지만, 아래의 정답 코드에선 먼저 그 다음 문자를 확인한 후 건너뛸지 말지 정한다.
이렇게 하면 코드도 훨씬 더 간결하게 짤 수 있다.
코드
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class CroatiaAlphabet2941 {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String word = br.readLine();
char alphabet;
int count = 0;
for (int i=0; i<word.length(); i++) {
alphabet = word.charAt(i);
// StringIndexOutOfBoundsException 방지
if (i == word.length()-1) {
count++;
break;
}
switch(alphabet) {
case 'c':
alphabet = word.charAt(i + 1);
if (alphabet == '=' || alphabet == '-')
i++;
count++;
break;
case 'd':
alphabet = word.charAt(i + 1);
if (alphabet == '-')
i++;
else if (alphabet == 'z' && i<word.length()-2) { // StringIndexOutOfBoundsException 방지
alphabet = word.charAt(i+2);
if (alphabet == '=')
i += 2;
}
count++;
break;
case 'l': case 'n':
alphabet = word.charAt(i + 1);
if (alphabet == 'j')
i++;
count++;
break;
case 's': case 'z':
alphabet = word.charAt(i + 1);
if (alphabet == '=')
i++;
count++;
break;
default:
count++;
}
}
System.out.println(count);
}
}
(+ 23.09.05)
풀이2
위의 풀이들보다 시간은 오래 걸렸지만 다른 방법이니까 기록해본다.
- 크로아티아 알파벳들이 요소로 들어가있는 리스트 생성
- 입력받은 단어를 앞부터 2글자 혹은 3글자씩 자른 후 해당 부분이 리스트에 포함 되어있는지 확인
- 2글자로 자른 단어가 리스트에 포함되어 있지 않으면 뒤의 1글자를 더 포함해 총 3글자 단어로 다시 확인
- 2글자 단어가 포함된 경우 인덱스+1, 3글자 단어가 포함된 경우 인덱스+2
- StringIndexOutOfBounds 오류가 발생할 수 있으므로 단어 자르기 전에 확인
코드
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.List;
public class Main {
public static void main(String[] args) throws IOException {
List<String> croatia = Arrays.asList("c=", "c-", "dz=", "d-", "lj", "nj", "s=", "z=");
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String word = br.readLine();
int count = 0;
for (int i=0; i<word.length(); i++) {
if (i < word.length()-1 && croatia.contains(word.substring(i, i+2))) {
count++;
i++;
continue;
}
else if (i < word.length()-2 && croatia.contains(word.substring(i, i+3))) {
count++;
i += 2;
continue;
}
count++;
}
System.out.println(count);
}
}
'코딩테스트 > 백준' 카테고리의 다른 글
[백준 2751] 수 정렬하기 2 - Java (0) | 2022.12.04 |
---|---|
[백준 2869] 달팽이는 올라가고 싶다 - Java (0) | 2022.11.14 |
[백준 2563] 색종이 -Java (1) | 2022.10.28 |
[백준 5622] 다이얼 - Java (0) | 2022.10.19 |
[백준 4673] 셀프 넘버 - Java (+) (1) | 2022.10.18 |
댓글