[자료구조] 08. Trie(트라이)를 사용하여 검색 자동완성 기능을 구현해 본다.

Trie(트라이)를 사용하여 검색 자동완성 기능을 구현해 본다.

Trie 란?

그림과 같이 트리구조를 가지며 문자열을 효율적으로 검색하고 저장하기위해 단어의 글자를 노드로 이어져있으며 단어의 끝에는 끝을 확인 할 수 있는 확인자가 있는 구조이다.

자동완성에서 Trie를 쓰는 이유?

String 구조를 트리에 담아 검색한다고 가정해보자

트리의 대표적인 구조인 이진탐색트리와 비교해보면 String의 길이를 M이라고 했을때, 시간복잡도는 O(M*log(N)) 이고

Trie의 경우 시간복잡도는 O(M)이 된다. 즉, 시간복잡도면에서 우월한 성능을 보이기 때문에 자동완성에서 Trie를 사용한다고 볼 수 있다.

구현 코드

1. 메인 코드

# 노드 설정
class Node():
    def __init__(self, value):
        self.value = value
        self.fin = False # 단어가 끝났을 경우 해당 단어를 집어넣는다.
        self.next = dict()

# 트라이 설정
class Trie():
    def __init__(self):
        self.head = Node(None)
     
    # 단어 삽입
    def insert(self, string):
        curr_node = self.head
        
        for word in string:
            if word not in curr_node.next:
                curr_node.next[word] = Node(word)
            curr_node = curr_node.next[word]
        
        curr_node.fin = string
    
    # 자동완성 
    def auto_complete(self, string):
        curr_node = self.head
        
        result = []
        
        for word in string:
            if word not in curr_node.next:
                return "추천 검색어가 없습니다."
            else:
                curr_node = curr_node.next[word]
        
        if curr_node.fin:
            result.append(curr_node.fin)
            
        stack = list(curr_node.next.values())
        
        while stack:
            v = stack.pop()
            
            if v.fin:
                result.append(v.fin)
            stack.extend(list(v.next.values()))
            
        return print(result)
    
    # 검색기록 출력
    def show_list(self):
        curr_node = self.head
        stack = list(curr_node.next.values())
        result = []
        
        while stack:
            v = stack.pop()
            
            if v.fin:
                result.append(v.fin)
            stack.extend(list(v.next.values()))
        return print(result)

2. 결과

# 초기화
T = Trie()

# 단어 삽입
T.insert('string')
T.insert('str')
T.insert('stress')
T.insert('star')
T.insert('singer')
T.insert('sign')
T.insert('starcraft')
T.insert('southkorea')
T.insert('south korea')

# 자동완성 기능
T.auto_complete('soo')
T.auto_complete('st')
T.auto_complete('star')
T.auto_complete('south')

# 검색기록 출력
T.show_list()
# Result

# 자동완성
'추천 검색어가 없습니다.'
['star', 'starcraft', 'str', 'stress', 'string']
['star', 'starcraft']
['south korea', 'southkorea']

# 검색기록
['south korea', 'southkorea', 'sign', 'singer', 'star', 'starcraft', 'str', 'stress', 'string']

© 2020. All rights reserved.