일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- 파이썬
- divmod
- 백준
- Re
- heapq
- 카카오
- 재귀함수
- 동적 계획법
- 수학
- lambda
- 정규식
- Zip
- BFS
- backjoon
- java
- 이분탐색
- 위클리 챌린지
- 그리디
- 추석맞이 코딩챌린지
- Combinations
- 프로그래머스
- 다익스트라
- programmers
- 정렬
- 자바
- dfs
- python
- Set
- KAKAO BLIND RECRUITMENT
- DateTime
- Today
- Total
상상쓰
[프로그래머스] 가사 검색 본문
https://programmers.co.kr/learn/courses/30/lessons/60060
저번에 풀었던 [3차] 자동완성에서 썼던 Trie 자료구조를 이용하였다.
'?' 가 접두사 아니면 접미사로만 존재하기 때문에 두 개의 dictionary 를 만들어 검색할 수 있도록 하였다.
예를 들어, 'frodo' 를 dictionary에 추가시키면
{'f': {'*': [5], 'r': {'*': [5], 'o': {'*': [5], 'd': {'*': [5], 'o': {'*': [5]}}}}}} 이고 '*' 는 그 위치의 문자를 가진 문자열의 길이가 5인 것이 하나 존재한다는 의미이다.
'front', 'frost' 과 'fronzen'를 추가시키면,
{'f': {'*': [5, 5, 5, 6], 'r': {'*': [5, 5, 5, 6], 'o': {'*': [5, 5, 5, 6], 'd': {'*': [5], 'o': {'*': [5]}}, 'n': {'*': [5], 't': {'*': [5]}}, 's': {'*': [5], 't': {'*': [5]}}, 'z': {'*': [6], 'e': {'*': [6], 'n': {'*': [6]}}}}}}} 로
'f' 로 시작하는 문자열은 길이가 5인 것이 세 개, 6인 것이 한 개 존재한다는 것이고, 'f' -> 'r' -> 'o' -> 'z' 에서 '*' 의 값이 [6] 이기 때문에 접두사가 'froz' 로 해당하는 문자열은 길이가 6인 것이 한 개 존재한다는 것이다.
즉, 완성한 dictionary 를 통해 'fro??' 와 일치하는 문자열을 찾을 때는 '?' 가 나오기 전에 'f' -> 'r' -> 'o' 에서의 '*' 에 해당하는 배열의 원소 중에서 'fro??' 의 길이인 5의 개수를 구하면 된다.
class Trie:
dictionary = {}
dictionaryReverse = {}
length = []
def insert(self, string):
current_dic = self.dictionary
current_dicReverse = self.dictionaryReverse
N = len(string)
self.length.append(N)
for i in range(N):
C = string[i]
R = string[N-1-i]
if C not in current_dic:
current_dic[C] = {'*' : [N]}
else:
current_dic[C]['*'].append(N)
current_dic = current_dic[C]
if R not in current_dicReverse:
current_dicReverse[R] = {'*' : [N]}
else:
current_dicReverse[R]['*'].append(N)
current_dicReverse = current_dicReverse[R]
def search(self, string):
current_dic = self.dictionary if string[0] != '?' else self.dictionaryReverse
string = string if string[0] != '?' else string[::-1]
N = len(string)
if string[0] == '?':
return self.length.count(N)
else:
for i in string:
if i in current_dic:
current_dic = current_dic[i]
else:
if i != '?':
return 0
else:
return current_dic['*'].count(N)
def solution(words, queries):
answer = []
T = Trie()
for i in words:
T.insert(i)
for i in queries:
answer.append(T.search(i))
return answer
print(solution(['frodo', 'front', 'frost', 'frozen', 'frame', 'kakao'], ['fro??', '????o', 'fr???', 'fro???', 'pro?'])) # [3, 2, 4, 1, 0]
'Coding Test' 카테고리의 다른 글
[프로그래머스] 튜플 (0) | 2021.07.23 |
---|---|
[백준] 소수 최소 공배수 (0) | 2021.07.22 |
[프로그래머스] 오픈채팅방 (0) | 2021.07.21 |
[백준] 최고의 피자 (0) | 2021.07.20 |
[프로그래머스] 전화번호 목록 (0) | 2021.07.19 |