문제 제목 : 크로아티아 알파벳
문제
예전에는 운영체제에서 크로아티아 알파벳을 입력 할 수가 없었다.
따라서, 다음과 같이 크로아티아 알파벳을 변경해서 입력했다.
크로아티아 알파벳 | 변경 |
---|---|
č | c= |
ć | c- |
dž | dz= |
đ | d- |
lj | lj |
nj | nj |
š | s= |
ž | z= |
예를 들어, ljes=njak
는,
크로아티아 알파벳 6개 (lj, e, š, nj, a, k) 로 이루어져 있다.
단어가 주어졌을 때, 몇 개의 크로아티아 알파벳으로 이루어져 있는지 출력한다.
dž는 무조건 하나의 알파벳으로 쓰이고, d와 ž가 분리된 것으로 보지 않는다.
lj 와 nj 도 마찬가지이다.
위 목록에 없는 알파벳은 한 글자씩 센다.
입력
첫째 줄에 최대 100 글자의 단어가 주어진다.
알파벳 소문자와 -
, =
로만 이루어져 있다.
단어는 크로아티아 알파벳으로 이루어져 있다.
문제 설명의 표에 나와있는 알파벳은 변경된 형태로 입력된다.
출력
입력으로 주어진 단어가 몇 개의 크로아티아 알파벳으로 이루어져 있는지 출력한다.
예제 입력 1
ljes=njak
예제 출력 1
6
예제 입력 2
ddz=z=
예제 출력 2
3
예제 입력 3
nljj
예제 출력 3
3
예제 입력 4
c=c=
예제 출력 4
2
예제 입력 5
dz=ak
예제 출력 5
3
이번 문제에서는 일반적인 알파벳 (a, b, c, ...) 가 아니라,
크로아티아 알파벳 형식으로 들어온다.
하지만, 여기서 크로아티아와 일반 알파벳의 차이점이 존재한다.
특정 크로아티아 알파벳은,
2 길이에 1개,
3 길이에 1개
그리고 나머지에 해당한다면, 1 길이에 1개로 취급하는 것이다.
그리고 우리가 구해야 하는 것 은,
주어진 크로아티아 문장에서, 크로아티아 식 알파벳의 개수를 구하는 것이다.
그렇다면, dz
, dz=
는 길이 2, 길이 1로 순서대로 치환된다.
그렇다는 것은, 앞으로 어떤 글자가 나올지 모르는 상황이므로, 길이도 예상할 수 없다는 것이다.
하지만, 우리에게는 모든 문자열이 한번에 주어진다.
따라서, 하나의 알파벳만으로 인식할 수 없는 모든 크로아티아 알파벳들을 미리 색출하는 방식이 존재한다.
마크다운 자체의 java 양식으로 컴파일 하지 않고 계속 도전하다가, 몇 가지 문제점을 발견했다.
아마, 이 문제를 풀지 못해 해답을 보지 않고 풀었을 것이다.
이 예시의 문제점은 몇 가지가 존재한다.
- 일치하는 크로아티아 문자를 지운다면, 앞 뒤 부분이 합쳐져 의도치 않은 또 다른 크로아티아 알파벳이 될 수 있다.
- 그리고 크로아티아 문자 자체의 중복성 문제인데,
dz=
,z=
이 문자열이 감지되었을 때,
해당 문자열이 두 번 감지된다는 것이 문제이다.
나 스스로의 길을 찾고 이를 직접 구현하고 싶었지만,
내가 직접 커스텀 구현을 할 수 있는 것은 결국 str.replace
메서드를 사용하지 않고,
직접 감지하여 해당 문자열을 삭제하고, 그 내부에 숫자를 넣어 아예 감지하지 못하게 하는 것이 끝이었다.
내가 좀 더 알고리즘적 사고가 활발했다면 다른 방식을 찾을 수 있었을까?
다시 풀게 된 이 크로아티아 문제의 풀이법을 보게 되었다.
하지만, 재배치 해야 하는 이유는, dz=
, z=
라는 것을 직접 감지했기에,
한 발자국 나아감을 느낀다.
Answer - 각 크로아티아 알파벳 숫자로 치환
import java.util.*;
import java.io.*;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String[] croaStr = {"c=", "c-", "dz=", "d-", "lj", "nj", "s=", "z="};
String str = br.readLine();
// 크로아티아 알파벳을 기준
for (int i = 0; i < croaStr.length; i++) {
String word = croaStr[i];
int wordLen = word.length();
for(int j = 0; j <= str.length() - wordLen; j++) {
String cutStr = str.substring(j, j + wordLen);
if (cutStr.equals(word)) {
str = str.substring(0, j) + "0" + str.substring(j + wordLen);
}
}
}
System.out.println(str.length());
}
}
'백준-단계별로 풀어보기 > 6-심화 1' 카테고리의 다른 글
백준 10988 Java - 팰린드롬인지 확인하기 (0) | 2024.09.18 |
---|---|
백준 2444 Java - 별 찍기 - 7 (1) | 2024.09.18 |
백준 3003 Java - 킹, 퀸, 룩, 비숍, 나이트, 폰 (0) | 2024.09.17 |