백준

99클럽 코테 스터디 8일차 TIL - 백준 9996번 : 한국이 그리울 땐 서버에 접속하지

킴준현 2025. 4. 9. 13:15

항해99 클럽 코테 스터디 7일차 TIL - 자바 미들러 4/9 (수요일)

https://www.acmicpc.net/problem/9996

✅ 문제

📌  접근방법

문자열을 * 기준으로 나누고 패턴을 배열에 저장한다.

*가 가운데에 있는 경우, 맨 앞에 있는 경우, 맨 뒤에 있는 경우 총 3가지로 나누었다.

 

🔑 풀이

❗️ 초기 풀이 (틀림)

import java.io.*;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br =  new BufferedReader(new InputStreamReader(System.in));
        int N = Integer.parseInt(br.readLine());

        String pString = br.readLine(); // pattern String
        String[] pattern = pString.split("\\*");

        for (int i = 0; i < N; i++) {
            boolean match = false;
            String text = br.readLine();

            // *가 단어에서 가운데에 있는 경우
            if(pattern.length == 2) {
                if(text.startsWith(pattern[0]) && text.endsWith(pattern[1])) {
                    match = true;
                }
            } else { // * 가 맨앞 혹은 맨뒤에 위치
                if(pString.toCharArray()[0] == '*') { // *가 맨앞
                    if(text.endsWith(pattern[0])) {
                        match = true;
                    }
                } else { // *가 맨뒤
                    if(text.startsWith(pattern[0])) {
                        match = true;
                    }
                }
            }
            
            if(match)
                System.out.println("DA");
            else
                System.out.println("NE");
        }
    }
}

반례

 

abc는 ab로 시작하는 것도 맞고, bc로 끝나는 것도 맞지만 ab*bc 패턴과 일치하지 않는다.

 

맨 앞, 맨 뒤 부분은 맞아도 문자열 길이가 부족해서 사실상 패턴 매칭이 불가능한 경우인데, 그걸 통과시켜버리는 오류가 발생한다.

그래서 마지막 조건문에 길이 비교 조건(패턴에서 * 제외한 나머지 부분 길이  <= 입력 문자열 길이)를 추가했다.

 

🔑 해답

import java.io.*;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br =  new BufferedReader(new InputStreamReader(System.in));
        int N = Integer.parseInt(br.readLine());

        String pString = br.readLine(); // pattern String
        String[] pattern = pString.split("\\*");

        for (int i = 0; i < N; i++) {
            boolean match = false;
            String text = br.readLine();

            // *가 단어에서 가운데에 있는 경우
            if(pattern.length == 2) {
                if(text.startsWith(pattern[0]) && text.endsWith(pattern[1])) {
                    match = true;
                }
            } else { // * 가 맨앞 혹은 맨뒤에 위치
                if(pString.toCharArray()[0] == '*') { // *가 맨앞
                    if(text.endsWith(pattern[0])) {
                        match = true;
                    }
                } else { // *가 맨뒤
                    if(text.startsWith(pattern[0])) {
                        match = true;
                    }
                }
            }
            
            if(match && pString.length() - 1 <= text.length())
                System.out.println("DA");
            else
                System.out.println("NE");
        }
    }
}

 

split() 메서드는 정규표현식(Regex)를 인자로 받는다.

"|", "*", ".", "&", "^" 등의 특수문자를 정규표현식(Regex)으로 사용하는 경우,

split() 함수 안에서 \\ (백슬래시 2번)을 넣어줘야한다.

 

정규표현식에서 *는 특수문자이면 문자 그대로 쓰고 싶으면 \* 라고 써야되는데,

자바 문자열 안에서 \ 는 excape 문자라서 \\* 이렇게 써야 최종적으로 정규표현식에서 * 하나로 인식된다.

 


참고

문자열 자르기 함수 split() 함수 특수문자 사용