2025. 5. 10. 22:36ㆍ알고리즘
https://www.acmicpc.net/problem/2941
문제설명
문자열을 입력받으면 해당 문자열에 크로아티아 알파벳을 몇 개나 포함하고 있는지 출력하는 문제이다. 크로아티아 알파벳이 아닌 일반 알파벳들은 한 글자씩 센다.
다만, 주의해야할 점은 "dz="의 경우 "z=" 값을 가지고 있어 문자열을 탐색할 때 2개가 포함되어있다라고 값을 반환할 수도 있기에 "dz="이 포함되어있을 경우에는 따로 조건을 추가해야한다.
코드
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(System.out));
String word = reader.readLine();
writer.write(String.valueOf(countCroatiaAlphabet(word)));
writer.newLine();
writer.flush();
writer.close();
reader.close();
}
private static int countCroatiaAlphabet(String word) {
String[] words = word.split("");
int result = 0;
int cnt = 0;
boolean[] isCheckedIdx = new boolean[word.length()];
for (int i = 1; i < words.length - 1; i++) {
char firstWord = words[i - 1].charAt(0);
char secondWord = words[i].charAt(0);
char thirdWord = words[i + 1].charAt(0);
String firSecThrWord = String.valueOf(firstWord) + String.valueOf(secondWord) + String.valueOf(thirdWord);
if (firSecThrWord.equals("dz=")) {
isCheckedIdx[i - 1] = isCheckedIdx[i] = isCheckedIdx[i + 1] = true;
cnt++;
result++;
}
}
for (int i = 1; i < words.length; i++) {
char firstWord = words[i - 1].charAt(0);
char secondWord = words[i].charAt(0);
String firSecWord = String.valueOf(firstWord) + String.valueOf(secondWord);
if (firSecWord.equals("c=") || firSecWord.equals("c-") || firSecWord.equals("d-") || firSecWord.equals("lj")
|| firSecWord.equals("nj") || firSecWord.equals("s=") || firSecWord.equals("z=")) {
isCheckedIdx[i - 1] = isCheckedIdx[i] = true;
result++;
}
}
result -= cnt;
for (int i = 0; i < isCheckedIdx.length; i++) {
if (!isCheckedIdx[i]) {
result++;
}
}
return result;
}
}
코드설명
words 배열은 입력받은 문자열을 한 글자씩 담고 있는 배열이다. 해당 배열은 후에 2글자, 3글자씩 문자열을 탐색해야할 때 사용한다.
result 변수는 크로아티아 알파벳이 몇 개 포함되고 있는지 세는 변수이다.
cnt 변수는 "dz="만을 위한 변수인데, 만약 입력받은 문자열에 "dz="가 몇 개 포함되어있는지 개수를 세고, 후에 result와 뺄셈을 하게 된다. 뺄셈을 하는 이유는 "dz="에 "z="이 포함되어있고 2글자씩 탐색할 때 "z="을 또 탐색하게 되기때문에 "dz="의 "z="을 또 추가로 세기 때문.
isCheckedIdx 배열은 크로아티아 알파벳을 탐색하여 찾았을 때 찾은 단어들의 각 인덱스에 맞게 찾았음을 저장하는 변수이다. 좀 설명이 어려워졌는데, 예시를 들어보자면, "ljes=njak" 의 경우 "lj", "s=", "nj" 가 크로아티아 알파벳인데, "lj"의 경우 0, 1 인덱스에 위치해 있고, "s="은 3, 4에 위치, "nj"는 5, 6에 위치해있다. 그러면 이제 isCheckedIdx[0], isCheckedIdx[1], isCheckedIdx[3], isCheckedIdx[4], isCheckedIdx[5], isCheckedIdx[6] 값은 true가 된다. 나머지 값들은 false.
이 과정을 왜 하냐면, 우리가 크로아티아 알파벳을 찾은 후 그 외에 나머지 알파벳들을 한 글자씩 세야하는데, 크로아티아 알파벳을 제외한 곳에 한 글자씩 되어있는 알파벳들이 몇 개 있는지를 확인하고 추가적으로 더해줘야하기 때문이다.
그러니 isCheckedIdx[n] 이 true면 해당 인덱스의 알파벳은 이미 크로아티아 알파벳 확인 완료된 알파벳이고, false일 경우에는 크로아티아 알파벳이 아닌 일반적인 알파벳이라는 뜻을 가지게 된다.
그리고 for문의 경우 3글자씩 탐색 이후 2글자씩 탐색하였고 (2글자 먼저 탐색해도 상관 x) 이후에 "dz="이 포함된 만큼 result에서 빼줬으며, isCheckedIdx[n]이 false인 개수만큼 result를 플러스하여 해결했다.
'알고리즘' 카테고리의 다른 글
[백준] 5622번: 다이얼 (JAVA) (0) | 2025.05.08 |
---|---|
[백준] 2153번: 소수 단어 (JAVA) (0) | 2022.03.03 |
[백준] 2902번: KMP는 왜 KMP일까? (JAVA) (0) | 2022.01.31 |
[백준] 10987번: 모음의 개수 (JAVA) (0) | 2022.01.23 |
[백준] 4143번: 다음 소수 (JAVA) (0) | 2022.01.20 |