1013번 문제는 정규표현식과 관련된 문제입니다. 파이썬의 정규표현식 모듈(re 모듈)을 자주 쓰는 편이라 금방 풀 줄 알았는데, 한 방에 해결해주는 re 모듈의 method를 모르고 있다가 몇 번의 오답 끝에 풀게 됐네요... 왜 틀렸는지도 조금만 서술해 가면서 짧게 다루고 넘어가도록 하겠습니다.
먼저, 정규표현식이라고 하면 컴퓨터가 문자열을 input으로 받았을 때, 사용자가 원하는 문자열만을 매치시켜 줄 수 있도록 해주는 일종의 규칙 혹은 패턴이라고 할 수 있습니다. 문제에서는 실제로 정규표현식에 사용하는 3가지 표현을 이용해 예제를 설명하였습니다. 3가지 표현을 간단히 짚고 넘어가면,
- + : "+ 바로 앞의 문자가 1번 이상 등장함" 을 의미합니다. 예를 들면, 정규표현식 "100+"는 100, 1000, 10000, 100000 등이 이 정규표현식에 매치됩니다. 정규표현식이 생소하신 분들이 간혹 여기서 "100100"이 매치된다고 생각할 수 있습니다. 100이 반복된다고 생각할 수 있으니까요. 하지만 여기서는 바로 앞 문자만을 의미하고 "100100"은, 가령, "(100)+" 과 매치된다고 할 수 있습니다. 괄호 ()에 대해서는 바로 이어서 설명할게요.
- ( ) : "괄호 안의 문자를 하나로 묶음"을 의미합니다. 바로 위의 예시(정규표현식 "(100)+")와 같이, 특정 문자들을 하나의 문자로 묶어 특정 문자가 아닌 문자의 묶음을 반복을 매치시키고 싶을 때 주로 사용됩니다.
- | : "또는"을 의미합니다. 예를 들면, 정규표현식 "(100+1+|01)"는 정규표현식 "100+1+"과 매치되거나 "01"과 매치, 혹은 그 둘에 모두 해당될 때 최종 매치합니다.
정규표현식의 기호들은 이외에도 정말 많습니다. 정규표현식의 개념과 파이썬에서의 사용법과 관련된 내용들은 이 문서 시리즈에 매우 친절하게 설명되어 있습니다. 정규표현식에 생소하신 분들은 가볍게 읽고 따라한 뒤 오시면 좋을 것 같습니다. 문제에 소개된 기호들은 어렵지 않으나, 실전에서 정규표현식의 사용은 위의 세 기호로는 해결할 수 없는 문제들이 많습니다. 또한, 정규표현식을 잘 알아두면 문자열을 처리하는데 있어서 효율을 극대화 해주므로 이왕 공부를 시작하셨다면, 시간 조금 들여보시는 것도 좋겠다는 말씀 드립니다!
Hint!
먼저, 정규표현식을 단순히 사용하면 되겠다고 생각을 한 이후에 바로 와 별거 아니네!!! 하면서,
sign = input()
p = re.compile('(100+1+|01)+')
m = p.match(sign)
이 코드들을 작성하셨을지도 모릅니다. 이 코드들은 문제에서 원하는 대로 제대로 작동하지 않는데요, 그 이유는 마지막 줄에
if m: print("Match:", m.group())
를 추가해보시면 대충 알 수 있습니다. 매치가 되기는 되는데, 그 결과가 입력된 문자열의 일부인 경우가 있습니다(전체를 해석하기 이전에 이미 매치된 문자열이 있는 경우 그것을 먼저 반환하는 경우가 됩니다.). 그것은 문제의 결과와는 어긋나죠. 결과는, 입력된 문자열 전체가 주어진 정규표현식에 매치가 될 수 있느냐 하는 것입니다.
이 경우에는, p.match() 보다는 p.fullamatch()를 사용하면 오로지 입력된 문자열 전체가 매치가 되는지 확인합니다. 즉, 문자열을 해석하는 과정에서 정규표현식과 매치되는 문자가 있다고 하더라도 그것을 스킵하고 입력된 문자열 전체를 보는 것입니다. 제가 장황하게 설명했지만... 사실 위의 코드와 큰 차이는 없습니다.
아래의 코드로 성공하였습니다.
import re
import sys
T = int(sys.stdin.readline())
results = []
for _ in range(T):
sign = sys.stdin.readline().replace('\n', '')
p = re.compile('(100+1+|01)+')
m = p.fullmatch(sign)
if m: results.append("YES")
else: results.append("NO")
for result in results:
sys.stdout.write(str(result)+'\n')
'Python > 백준 알고리즘' 카테고리의 다른 글
[백준 알고리즘: python 3] #1016 - 제곱 ㄴㄴ수 (2) | 2019.11.02 |
---|---|
[백준 알고리즘: python 3] #1015 - 수열 정렬 (0) | 2019.11.01 |
[백준 알고리즘: python 3] #1012 - 유기농 배추 (0) | 2019.09.10 |
[백준 알고리즘: python 3] #1011 - Fly me to the Alpha Centauri (0) | 2019.09.08 |
[백준 알고리즘: python 3] #1010 - 다리 놓기 (0) | 2019.09.08 |