백준-단계별로 풀어보기/6-심화 1

백준 2941 Java - 크로아티아 알파벳

코딩크리처 2024. 10. 25. 20:52

문제 제목 : 크로아티아 알파벳


문제

예전에는 운영체제에서 크로아티아 알파벳을 입력 할 수가 없었다.

따라서, 다음과 같이 크로아티아 알파벳을 변경해서 입력했다.

크로아티아 알파벳 변경
č c=
ć c-
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());
    }
}