와드의 블로그

9996번: 한국이 그리울 땐 서버에 접속하지 본문

PS/B.O.J

9996번: 한국이 그리울 땐 서버에 접속하지

Ward 2026. 3. 20. 11:57

문제

어떤 파일 이름이 주어졌을 때, 해당 파일 이름이 특정 패턴과 일치하는지 판별하는 문제입니다. 패턴은 알파벳 소문자 여러 개와 별표(*) 하나로 이루어져 있습니다. 별표는 빈 문자열을 포함하여 임의의 문자열로 변환될 수 있습니다.

  • 입력: 첫째 줄에 파일의 개수 N이 주어지고, 둘째 줄에 패턴이 주어집니다. 다음 N개의 줄에는 파일 이름이 주어집니다.
  • 출력: 각 파일 이름이 패턴과 일치하면 "DA", 일치하지 않으면 "NE"를 출력합니다.

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

풀이 1: 접두사와 접미사 분리 (String 메서드 활용)

패턴의 유일한 별표(*)를 기준으로 앞부분(접두사)과 뒷부분(접미사)을 분리하여 각 문자열을 검사하는 방식으로 해결할 수 있습니다. 자바의 문자열 처리 메서드를 활용하면 매우 쉽게 구현할 수 있습니다.

  1. 패턴 분리: indexOf('*')를 통해 별표의 위치를 찾고, substring()을 사용하여 별표 앞부분(pre)과 뒷부분(suf)으로 문자열을 나눕니다.
  2. 길이 예외 처리 (핵심): 검사할 문자열 s의 길이가 접두사와 접미사의 길이 합보다 짧다면, 두 패턴이 겹치게 되므로 무조건 일치하지 않는 것으로 판별해야 합니다. (예: 패턴이 a*a일 때, 문자열이 a라면 길이는 짧지만 startsWith("a")와 endsWith("a")를 모두 통과하는 논리적 오류가 발생할 수 있습니다.)
  3. 접두사/접미사 검사: 문자열의 길이가 충분하다면, startsWith(pre)와 endsWith(suf)를 통해 앞뒤 패턴이 모두 일치하는지 확인합니다.

코드 1

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

public class Main {
    public static void main(String[] args) throws IOException {
       BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
       BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));

       // 파일의 개수 입력
       int n = Integer.parseInt(br.readLine());

       // 패턴 입력
       String pattern = br.readLine();

       // 별표(*)를 기준으로 접두사(pre)와 접미사(suf) 분리
       int idx = pattern.indexOf('*');
       String pre = pattern.substring(0, idx);
       String suf = pattern.substring(idx + 1);

       while (n-- > 0) {
          String s = br.readLine();
          
          // 1. 문자열의 길이가 접두사 + 접미사 길이보다 짧으면 겹치므로 NE
          if (s.length() < pre.length() + suf.length()) {
             bw.write("NE\n");
             continue;
          }

          // 2. 접두사로 시작하고 접미사로 끝나는지 확인
          if (s.startsWith(pre) && s.endsWith(suf)) {
             bw.write("DA\n");
          } else {
             bw.write("NE\n");
          }
       }

       bw.flush();
       bw.close();
       br.close();
    }
}

풀이 2: 정규표현식(Regex) 활용

자바의 정규표현식을 사용하면 복잡한 길이 검사나 분리 과정 없이 아주 간결하게 풀 수 있습니다.

  1. 정규식 치환: 문제에서 주어진 별표(*)는 임의의 문자열을 뜻하므로, 이를 정규표현식 문법에 맞게 .* (임의의 문자 0개 이상)로 치환합니다.
  2. 패턴 매칭: String.matches() 메서드를 사용하여 치환된 정규식 패턴과 문자열이 일치하는지 검사합니다.

코드 2

import java.io.*;

public class Main {
    public static void main(String[] args) throws IOException {
       BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
       BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));

       int n = Integer.parseInt(br.readLine());
       String pattern = br.readLine();

       // '*' 기호를 정규표현식의 '.*' (임의의 문자 0개 이상)로 치환
       String regex = pattern.replace("*", ".*");

       while (n-- > 0) {
          String s = br.readLine();
          
          // matches() 메서드로 한 번에 검사
          if (s.matches(regex)) {
             bw.write("DA\n");
          } else {
             bw.write("NE\n");
          }
       }

       bw.flush();
       bw.close();
       br.close();
    }
}

알고리즘 분류

문자열 처리 (String), 파싱 (Parsing), 정규표현식 (Regular Expression)

'PS > B.O.J' 카테고리의 다른 글

1620번: 나는야 포켓몬 마스터 이다솜  (0) 2026.03.20
2559번: 수열  (0) 2026.03.20
11655번: ROT13  (0) 2026.03.19
1159번: 농구 경기  (0) 2026.03.19
10988번: 팰린드롬인지 확인하기  (0) 2026.03.19