Algorithm/문제풀이 Python
프로그래머스 레벨2 - 카카오 인턴 2019 튜플
nauni
2020. 12. 30. 10:51
문제주소
programmers.co.kr/learn/courses/30/lessons/64065
내 풀이
import re
def solution(s):
answer = []
parsed = re.compile("(?<={).+?(?=})")
newS = list()
for item in parsed.findall(s[1:]):
newS.append(set(map(int, item.split(","))))
newS = sorted(newS, key=lambda x : len(x))
answer.append(newS[0].pop())
for i in range(1,len(newS)):
answer.append((newS[i]-set(answer)).pop())
return answer
정규표현식
정규표현식 공부한 것을 처음 사용해보는거라 어려움이 있었다. 먼저 {}를 기준으로 문자열을 파싱하고 싶었다. 처음에는 (?={).+(?=}) 이렇게 작성하였는데 제대로 작동하지 않았다. 탐욕적 탐색을 제한하기 위해서는 .+ 옆에 ? 를 추가하면 된다. 앞부분의 {도 탐색하기 위해서는 (?={) 가 아니라 <= 로 해주어야 후방탐색이 가능해 앞 뒤로 {} 문자를 기준으로 파싱이 가능하다. ( 전방탐색: ?= , 후방탐색: ?<= )
집합 원소 꺼내기 (pop)
테스트 케이스 일부가 통과가 안 되었는데 원인은 pop 이었다. pop 은 집합의 원소를 꺼내기 때문에 꺼내고 나면 남는 원소가 없다. 원래는 newS[i] - newS[i-1] 로 작성하였는데 pop으로 꺼내버리면 원소가 남지 않기 때문에 통과가 안 된 것이었다.
다른사람 풀이 참고
다들 쉽다는데 나는 생각보다 어려웠다..
카운터로 숫자의 갯수를 카운팅해서 많은 순서대로 answer에 넣어주는 풀이가 가장 인상깊었다.
문자열에서 한 캐릭터가 아닌 숫자 단위로 파싱하는게 어려웠는데 \d+ 로 하면 1개 이상의 숫자를 가져올 수 있다.
import re
def solution(s):
answer = []
print(re.findall('\d+', s))
# ['20', '1', '1']
return answer
print(solution("{{20,1},{1}}"))
정리
문자열을 앞 뒤를 자르고 },{ 기준으로 split 할 수도 있지만 정규표현식을 처음 사용한데 의의가 있다. 문자열 파싱과 정렬해서 원소를 빼내는 것이 포인트였다. 이 문제가 다소 어려웠던 걸 보니 문자열 파싱을 좀 더 연습해야 겠다. 다음번엔 Counter 라이브러리를 사용해 봐야겠다.