[백준] 2941 : 크로아티아 알파벳 : 문자열

Ureca.·2024년 10월 12일

[백준]

크로아티아 알파벳


문자열 구현 문제 중 하나로 문자열에 익숙해지자 라는 유형의 문제이다.
문제 자체는 해당하는 문자열을 치환해서 하나로 카운팅 하는 방식으로 풀어가면 될 듯 합니다.
풀어보면서 '이걸 for문을 돌리면서 굳이 카운팅을 해야 하는건가? 규칙에 저촉되지 않는 방식으로 치환해두면 바로 계산이 될 것 같은데?'
라는 생각을 하면서 풀었었고, 여타 블로그 세 군데 정도 둘러보면서 어떤 방식으로 풀었는지 비교를 했었습니다.

보면서 푸는 방향성이 좀 달라보이길래 이렇게 블로그로 정리를 해봅니다. 사실 정리할 정도의 문제는 아닌듯하나, 저 또한 초보적인 문제를 밟고 올라왔던 기억이 있기 때문에 조금이라도 도움이 되고자 했으면 합니다.

제가 생각했던 것은 두 방식이 있었는데, 첫째로는 문자열을 입력받으면 이를 for문을 돌리면서 하나의 문자열로 바꿔야 하는 것을 찾으면 바꾸면서 카운팅을 해주는 방식이었습니다. 이것이 대부분의 블로그에서 사용하고 있는 코딩입니다. 그러나 저는 이를 사고해내기까지에 많은 시간이 소요됐어서 이건 제 방식이 아니었구나라고 생각을 했고, 바로 다음 방식을 사용했습니다.

한 줄의 문자열을 받게 되면 받는 즉시 치환을 해서 다시 저장하는 방식입니다.
replaceAll을 사용했고, replaceAll(regex, replacement)에서 regex부분에는 바꿀 문자열, replacement에는 바꾼 후의 문자열을 적습니다.
그리고 어떠한 알파벳에도 들어가지 않게끔 바꾼 후의 문자열을 .로 사용했습니다.

import java.io.*;
import java.util.*;

public class Main {
    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String str = br.readLine();
        str = str.replaceAll("c=", ".");
        str = str.replaceAll("c-", ".");
        str = str.replaceAll("dz=", ".");
        str = str.replaceAll("d-", ".");
        str = str.replaceAll("lj", ".");
        str = str.replaceAll("nj", ".");
        str = str.replaceAll("s=", ".");
        str = str.replaceAll("z=", ".");

        System.out.println(str.length());
    }
}

기본 코드문은 이렇고, 이를 더 줄이고 싶었습니다. 그래서 이를 다음과 같이 변경했습니다.

import java.io.*;
import java.util.*;

public class Main {
    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String str = br.readLine();
        str = str.replaceAll("c=", ".").replaceAll("c-", ".")
                .replaceAll("dz=", ".").replaceAll("d-", ".")
                .replaceAll("lj", ".").replaceAll("nj", ".")
                .replaceAll("s=", ".").replaceAll("z=",".");

        System.out.println(str.length());
    }
}

결국 쉬운 문제였기 때문에 알고리즘을 설명할 필요는 없을거 같아요. 다만 replace를 사용할 때 주의점이 있어요.

import java.io.*;
import java.util.*;

public class Main {
    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String str = br.readLine();
        str.replaceAll("c=", ".");
        str.replaceAll("c-", ".");
        str.replaceAll("dz=", ".");
        str.replaceAll("d-", ".");
        str.replaceAll("lj", ".");
        str.replaceAll("nj", ".");
        str.replaceAll("s=", ".");
        str.replaceAll("z=", ".");

        for (int i = 0; i < str.length(); i++) {
            System.out.println(str.charAt(i));
        }
    }
}

첫 번째 코드와 차이가 보이시나요?
네. 문자열 치환을 한 이후에 다시 저장을 하지 않았습니다.
replaceAll메서드는 원본 문자열을 수정하는 것이 아니라, 치환된 새로운 문자열을 단순히 return만 해줍니다.
그렇기 때문에, 우리는 추가적으로 반환한 값을 다시 저장하기 위한 장치를 할 필요가 있는 것이고 저는 이를 str = 형태로 저장해준 것 입니다.

profile
한 편의 주마등이 망작이 될 수는 없잖아.

0개의 댓글