이 영역을 누르면 첫 페이지로 이동
butter_shower 블로그의 첫 페이지로 이동

butter_shower

페이지 맨 위로 올라가기

butter_shower

[Algorithm] 트라이(Trie)와 관련 문제들 (Python)

  • 2021.04.11 15:51
  • 알고리즘 Algorithm
글 작성자: _rian

트라이란?

문자열을 효과적으로 탐색하기 위한 자료구조로, 문자열을 순차탐색하는 방식이 아닌 트리로 접근하기 위해 만들어진 자료구조입니다. 주로 Prefix Tree, digital search Tre, retrieval tree라고도 불리는데, retrieval tree의 trie를 따와 트라이라고 일반적으로 불립니다.

트라이는 문자열을 key로 사용하는 동적은 set 또는 연관배열을 저장하는 트리의 확장된 구조입니다. 문자열을 탐색할 때 단순하게 하나씩 비교하지 않고 key로 노드들을 탐색해나가기때문에 매우 효율적이라는 장점이 있습니다. 단, 빠르게 탐색 가능하지만 각 노드에서 자식들에 대한 포인터들을 배열로 모두 저장하고 있다는 점에서 저장 공간의 크기가 크다는 단점이 있습니다.

위 사진을 보시면 아시다싶이 루트 노드에서 하나씩 뻗어가면서 자식 노드에는 하나의 문자(key)가 들어있고 그 밑의 자식 노드드들은 바로 위 부모 노드와 공통의 접두사를 공유하고 있습니다.

트라이는 탐색과 삽입을 지원하는 노드로 구성된 트리여서, 탐색은 키 문자열과 연관된 값을 반환하고 삽입은 문자열과 그 값을 삽입합니다. 키의 길이가 m일때 탐색과 삽입 모두 $O(m)$ 시간에 수행됩니다.

구현 방법

관련 문제 : LeetCode - 208. Implement Tree(Prefix tree)

 

Implement Trie (Prefix Tree) - LeetCode

Level up your coding skills and quickly land a job. This is the best place to expand your knowledge and get prepared for your next interview.

leetcode.com

위 문제는 한번 꼭 보시는 것을 추천합니다! 트라이를 어떻게 구현할 수 있을지에 관한 문제거든요 ㅎㅎ 파이썬으로 Trie 클래스를 만들어봅시다.

class Trie:

    def __init__(self):
        self.trie = {}  # root 

    def insert(self, word):
        t = self.trie
        for c in word:
            if c not in t:
                t[c] = {}
            t = t[c]
        t['*'] = True # 끝이라는걸 알림

    def search(self, str)
        t = self.trie
        for c in word:
            if c not in t:
                return False
            t = t[c]
        return '*' in t

    def startsWith(self, prefix)
        t = self.trie
        for c in prefix:
            if c not in t:
                return False
            t = t[c]
        return True

한 문자를 입력할 때 해당 문자가 끝인 것을 알리기 위해 * 라는 키를 넣어줍니다. 탐색하는 함수의 경우에도 t = t[c] 가 자식노드를 계속해서 탐색해준다는 뜻입니다. 

 

Trie 문제

Leetcode 648. Replace Words

 

Replace Words - LeetCode

Level up your coding skills and quickly land a job. This is the best place to expand your knowledge and get prepared for your next interview.

leetcode.com

문제 풀이

class Solution:
    def replaceWords(self, dictionary: List[str], sentence: str) -> str:
        # 트라이 자료구조 만들기
        root = {}
        for dic in dictionary:
            t = root
            for c in dic:
                if c not in t:
                    t[c] = {}
                t = t[c]
            t['*'] = True

        answer = []
        for word in sentence.split():
            t = root
            res = ''

            if len(word) == 1:
                if word in t:
                    answer.append(word)
                    continue 

            flag = 0
            for c in word:
                if '*' in t:
                    answer.append(res)
                    flag = 1
                    break

                if c not in t:
                    answer.append(word)
                    flag = 1
                    break

                t = t[c]
                res += c

            if flag == 0:
                answer.append(res)

        return " ".join(answer)

먼저 트라이 구조를 만들어준 후 같은 prefix를 공유하는 단어가 트라이에 있으면 그 단어로 치환해주는 코드입니다. 있는지 없는지 여부는 *로 확인해주면 되고 검색하는 문자열보다 트라이에 있는 값이 더 짧은 경우를 확인하기 위해 flag를 같이 넣어주었어요.

사실 $O(N^3)$으로 풀 수 있는 문제고 통과는 되지만 효율성 측면에서 trie를 사용하는것이 더욱 좋다고 합니다 ㅎ.ㅎ 트라이 연습하실때 좋은 코드인 것 같아요.


다른 언어에서는 잘 모르겠는데, 파이썬에서는 아무래도 key-value로 들어가는 것이다 보니 딕셔너리 자료구조를 많이 사용하는 것 같습니다. 그냥 쉽게 코딩하려면 딕셔너리를 쓰고, 그렇지 않은 경우에는 따로 Node 클래스를 구현해주더라구요. 그래도 시간복잡도 측면에서는 비슷합니다.

트라이는 시간복잡도가 순차 탐색보다 훨씬 효과적이라는 장점이 있지만, 공간복잡도 측면에서는 별로 좋지가 않습니다. 당장 알파벳으로만 봐도.. a-z로 depth가 조금 깊어지면 ...... 엄청나게 많은 공간을 차지하게되기 때문에 코딩 환경에 따라 잘 확인해볼 필요가 있을 것 같아요 ㅎ.ㅎ

'알고리즘 Algorithm ' 카테고리의 다른 글

[Algorithm] 투포인터(Two Pointer) 알고리즘  (0) 2021.04.28
[Algorithm] DFS와 BFS 기본 개념 및 관련 문제들 (python)  (0) 2021.04.23
[Algorithm] 인프런 강좌 따라하며 배우는 알고리즘! 73장~75장  (0) 2020.07.08
[Algorithm] 인프런 강좌 따라하며 배우는 알고리즘! 72장  (0) 2020.07.05
[Algorithm] 인프런 강좌 따라하며 배우는 알고리즘! 70장 ~  (0) 2020.07.03

댓글

이 글 공유하기

  • 구독하기

    구독하기

  • 카카오톡

    카카오톡

  • 라인

    라인

  • 트위터

    트위터

  • Facebook

    Facebook

  • 카카오스토리

    카카오스토리

  • 밴드

    밴드

  • 네이버 블로그

    네이버 블로그

  • Pocket

    Pocket

  • Evernote

    Evernote

다른 글

  • [Algorithm] 투포인터(Two Pointer) 알고리즘

    [Algorithm] 투포인터(Two Pointer) 알고리즘

    2021.04.28
  • [Algorithm] DFS와 BFS 기본 개념 및 관련 문제들 (python)

    [Algorithm] DFS와 BFS 기본 개념 및 관련 문제들 (python)

    2021.04.23
  • [Algorithm] 인프런 강좌 따라하며 배우는 알고리즘! 73장~75장

    [Algorithm] 인프런 강좌 따라하며 배우는 알고리즘! 73장~75장

    2020.07.08
  • [Algorithm] 인프런 강좌 따라하며 배우는 알고리즘! 72장

    [Algorithm] 인프런 강좌 따라하며 배우는 알고리즘! 72장

    2020.07.05
다른 글 더 둘러보기

정보

butter_shower 블로그의 첫 페이지로 이동

butter_shower

  • butter_shower의 첫 페이지로 이동

검색

메뉴

  • All Categories
  • About Me
  • Guest Book

카테고리

  • 전체보기 (223)
    • 💫 주인장 이야기 (17)
    • 🌱 와글와글뻘글 (27)
    • IT Trends (11)
    • 주인장 일상 (0)
    • 📒 내 마음대로 독서 서평 (12)
    • 머신러닝 꿈나무 (30)
      • 기본 개념 (6)
      • Hands-on! (5)
      • Paper Review (5)
      • 캐린이의 Kaggle (1)
    • 알고리즘 Algorithm (33)
      • PS (8)
    • Computer Engineering (75)
      • Python (8)
      • Cloud Computing (9)
      • C (9)
      • C++ (0)
      • Java (6)
      • Django 장고 (4)
      • 임베디드 시스템 (10)
      • 병렬 처리(Parallel Processing) (9)
      • 데이터 통신 Data communication (4)
      • 유닉스 시스템 (Unix System) (3)
      • GitHub (1)
      • 마이크로 프로세서 (micro processor) (1)
      • 데이터 마이닝 (1)
    • Error Note 🚨 (3)
    • 영어 공부 (6)
      • Live Academy (6)
    • HOBBY (2)
      • Film Log (2)

최근 글

정보

_rian의 butter_shower

butter_shower

_rian

나의 외부 링크

  • Github
  • Facebook
  • Instagram
  • LinkedIn
  • Twitter

블로그 구독하기

  • 구독하기
  • RSS 피드

방문자

  • 전체 방문자
  • 오늘
  • 어제

티스토리

  • 티스토리 홈
  • 이 블로그 관리하기
  • 글쓰기
Powered by Tistory / Kakao. © _rian. Designed by Fraccino.

티스토리툴바