BOJ 1032 명령 프롬프트

명령 프롬프트

시간 제한 메모리 제한
2초 128MB

문제

시작 -> 실행 -> cmd를 쳐보자. 검정 화면이 눈에 보인다.
여기서 dir이라고 치면 그 디렉토리에 있는 서브디렉토리와 파일이 모두 나온다.
이때 원하는 파일을 찾으려면 다음과 같이 하면 된다.
dir *.exe라고 치면 확장자가 exe인 파일이 다 나온다.
“dir 패턴”과 같이 치면 그 패턴에 맞는 파일만 검색 결과로 나온다.
예를 들어, dir a?b.exe라고 검색하면 파일명의 첫 번째 글자가 a이고,
세 번째 글자가 b이고, 확장자가 exe인 것이 모두 나온다.
이때 두 번째 문자는 아무거나 나와도 된다.
예를 들어, acb.exe, aab.exe, apb.exe가 나온다.
이 문제는 검색 결과가 먼저 주어졌을 때,
패턴으로 뭘 쳐야 그 결과가 나오는지를 출력하는 문제이다.
패턴에는 알파벳”.” 그리고 ”?”만 넣을 수 있다.
가능하면 ?을 적게 써야 한다.
그 디렉토리에는 검색 결과에 나온 파일만 있다고 가정하고,
파일 이름의 길이는 모두 같다.

입력

첫째 줄에 파일 이름의 개수 N이 주어진다.
둘째 줄부터 N개의 줄에는 파일 이름이 주어진다.
N은 50보다 작거나 같은 자연수이고 파일 이름의 길이
모두 같고 길이는 최대 50이다.
파일이름은 알파벳과 “.” 그리고 “?”로만 이루어져 있다.

출력

첫째 줄에 패턴을 출력하면 된다.

예제 입력

3
config.sys
config.inf
configures

예제 출력

config????

풀이

간단한 2중 Loop를 사용해서 풀 수 있는 문제다.


주의해야 할 조건

  • N1일 경우
  • 이미 다른 패턴을 찾은 경우

다음의 두 가지 조건만 유의하면 어렵지 않게 해결할 수 있다.


반복법

파일의 개수만큼 반복 ❯ 파일의 이름의 길이만큼 반복
다음과 같은 2중 Loop를 사용하면된다.
다음과 같은 파이썬 코드로 표현할 수 있다.

for i in range(n - 1):
    for j in range(length):

n - 1번 반복한 이유는 현재 인덱스다음 인덱스비교해주기 때문에
n - 2번 째 인덱스와 n - 1번째 인덱스가 서로 비교가 된다.
n번 반복하게 되면 리스트의 비어있는 공간을 참조하여 비교하게 된다.


조건의 판단

현재 파일 이름j번째 문자와 다음 파일 이름j번째 문자를 비교하면 된다.
여기에서 주의해야 할 조건에서 언급한 이미 다른 패턴을 찾은 경우를 생각해야 한다.
예를 들어 테스트 케이스가 아래와 같을 경우 출력 결과는 ?표가 출력되어야 하지만

3
a
b
b

이미 다른 패턴을 찾은 경우를 생각하지 않게되면 2번째 파일이름인 b
3번째 파일이름인 b가 같아 b가 출력이 되는 경우가 발생한다.
다음의 예외를 생각하고 파이썬 코드로 표현하면 아래와 같다.

if file_name[i][j] is file_name[i + 1][j] \
    and pattern[j] is not '?':
    pattern[j] = file_name[i][j]

else:
    pattern[j] = '?'


코드 구현부

위의 설명을 토대로 코드를 작성하면 다음과 같다.

import sys

n = int(sys.stdin.readline().strip())
file_name = []

for _ in range(n):
    file_name.append(sys.stdin.readline().strip())

if n != 1 :
    length = len(file_name[0])
    pattern = [0] * length

    for i in range(n - 1):
        for j in range(length):
            if file_name[i][j] is file_name[i + 1][j] \
                and pattern[j] is not '?':
                pattern[j] = file_name[i][j]

            else:
                pattern[j] = '?'

    print(''.join(pattern))

else:
    print(file_name[0])


상세 설명

일단 파일의 개수가 1개인지 확인한 후 개수가 1개일 경우
삽입된 파일이름을 바로 출력해 주고, 개수가 1개가 아닐 경우
이름의 길이를 저장해 pattern = [0] * length과 같이 패턴 리스트를 초기화한다.
2중 Loop를 진행하며 조건을 판단하여 공통적인 패턴일 경우 문자를
패턴 리스트에 저장한다. 공통적인 패턴이 아닐 경우 패턴 리스트에 ?를 저장한다.
모든 루프를 탈출하게 되면 join 매서드를 사용해 패턴의 결과를 출력해준다.


결과

어렵지 않고 빠르게 해결할 수 있는 문제였다.
고려해야하는 예외들이 몇가지 존재하여 주의해서 생각하지 않는다면
예외를 찾는데 시간을 많이 걸릴 것 같다.😉😉
예외를 찾는데 어려움을 겪는다면 아래의 테스트 케이스들로 한번 테스트 해보길 바란다.

Input 3 3 3 3 3 2 1
  abc config.sys config.sys aaa a aa a
  bbc configures configures aba b ba  
  aba config.inf config.ins aca b    
Output ??? config???? config???s a?a ? ?a a

✅ 코드는 [여기]에서 확인할 수 있다.