[BOJ] 9996. 한국이 그리울 땐 서버에 접속하지

Jimeaning·2023년 4월 10일
0

코딩테스트

목록 보기
67/143
post-thumbnail

Python3

문제

입출력

키워드

  • 구현
  • 패턴 찾기
  • 정규 표현식 (특정한 규칙을 가진 문자열의 집합을 표현하는 데 사용하는 형식 언어)

주요 포인트

파일의 개수 n을 입력받는다.
패턴을 입력받는데, '*'을 기준으로 분리한다.
'*'을 기준으로 나눠진 패턴의 길이를 length 변수에 담는다.

반복문(n까지)
파일을 입력 받는다.

만약 length가 파일의 문자열 길이보다 길다면, NE를 출력한다.
패턴의 길이가 더 길면 절대 일치할 수 없기 때문이다.

파일의 길이가 더 긴 경우는 문자열을 슬라이싱해서 같은지 판단해야 한다.
패턴의 첫 번째 요소파일의 처음~pt[0]의 길이 문자열이 같고,
패턴의 두 번째 요소파일의 끝에서 pt[1]번째 길이부터 끝까지 문자열이 같으면
DA를 출력한다.

패턴: a*d
파일: abcd
	anestonestod
	facebook

이렇게 입력되었다고 가정하면 pt[0]file[:len(pt[0])]의 값은 각각 다음과 같다.

a a
a a
a f

pt[1]file[-len(pt[1]):]

d d
d d
d k

코드

n = int(input())
pt = input().split('*')
length = len(pt[0]) + len(pt[1])

for i in range(n):
    file = input()
    
    if length > len(file):
        print('NE')
    else:
        if pt[0] == file[:len(pt[0])] and pt[1] == file[-len(pt[1]):]:
            print('DA')
        else:
            print('NE')   

수정사항

(23.4.13 업데이트)
위 코드가 짧긴 하지만 -len(pt[1])처럼 가독성이 조금 떨어진다.

다음과 같이 코드를 개선하였다.

import sys

n = int(sys.stdin.readline())
pt = list(map(str, sys.stdin.readline().split('*')))
lft = pt[0].strip()
rgt = pt[1].rstrip('\n')

for _ in range(n):
    file = list(map(str, sys.stdin.readline().rstrip('\n')))
    
    if len(file) >= len(lft)+len(rgt):
        if lft == ''.join(file[:len(lft)]) and rgt == ''.join(file[len(file)-len(rgt):]):
            print('DA')
        else: print('NE')
    else:
        print('NE')
  • 파일을 리스트로 만든다
  • 파일의 길이가 *을 기준으로 왼쪽+오른쪽 문자열을 더한 것보다 짧으면 절대 일치할 수 없다.
    - 만약 패턴 왼쪽 문자열이 파일 이름의 첫 번째~왼쪽 문자열의 길이까지의 문자열과 같고, (lft == ''.join(file[:len(lft)]))
    패턴 오른쪽 문자열과 (파일 이름의 총 길이-패턴의 오른쪽 문자열 길이)~끝까지 문자열과 같다면 (rgt == ''.join(file[len(file)-len(rgt):]))
    일치한다고 출력한다.
    - 그 외는 일치하지 않는다.

h*n이라는 패턴이 주어졌을 때,
haaaaaan은 DA이지만 hanaaaa는 NE가 출력된다.

+23/5/17 추가

n = int(input())
a, b = input().split('*')

for _ in range(n) :
    file = input()
    
    if len(a) + len(b) > len(file) :
        print('NE')
    else :
        if file[:len(a)] == a and file[-len(b):] == b :
            print('DA')
        else :
            print('NE')

첫 번째 푼 것과 거의 유사하다.
*을 기준으로 문자열을 구분해서 a, b 변수에 넣어주었다.
(예시는 모두 *을 기준으로 한 글자씩만 있지만 패턴이 두 글자 이상 될 수 있음)

입력받은 파일 문자열의 인덱스 처음부터 ~ a의 길이까지가 패턴 a부분과 같고, 뒤에서 b 길이부터 ~ 끝까지의 문자열이 패턴 b와 같으면 DA 출력

hi*ih 이 패턴이면,
a에는 hi, b는 ih가 들어 간다.
파일 이름이 hiooooih 라면,
(앞에서부터 ~ a 길이)까지는 file[0:2]가 돼서 hi가 해당된다.
한편, b부분은 문자열의 뒤에서부터 확인해야 한다.
뒤에서 b길이부터 ~ 끝까지는 file[-2:] (= file[6:])로 ih이다.

피드백

file[-a:]는 파일의 끝에서 a번째부터 끝까지 문자열을 가지고 온다는 뜻이다.
특정 문자를 기준으로 문자열을 나누고 싶을 때는 split('문자')를 하면 된다.

search, find 무엇을 써야 하는지 고민이 되었다. 문자열을 슬라이싱 하는 문제였다.

참고

https://imzzan.tistory.com/146

profile
I mean

0개의 댓글