ํŠธ๋ผ์ด(Trie)

ํ‚ค์™€ ๊ฐ’์„ ์Œ์œผ๋กœ ๊ฐ–๋Š” ์—ฐ๊ด€ ๋ฐฐ์—ด ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•˜๋Š” ํŠธ๋ฆฌ ์ž๋ฃŒ ๊ตฌ์กฐ

์ฃผ๋กœ ์ž์—ฐ์–ด ์ฒ˜๋ฆฌ(NLP) ๋ถ„์•ผ์—์„œ ๋ฌธ์ž์—ด ํƒ์ƒ‰์„ ์œ„ํ•ด ์‚ฌ์šฉํ•œ๋‹ค. ๋ฌธ์ž์—ด์˜ ๊ฐ๊ฐ์˜ ๋ฌธ์ž ๋‹จ์œ„๋กœ ์ƒ‰์ธ์„ ๊ตฌ์ถ•ํ•œ ํ˜•ํƒœ์ด๋‹ค.

ํŠธ๋ผ์ด ์›๋ฆฌ

ํŠธ๋ผ์ด๋ฅผ ์ด์šฉํ•œ ๋ฌธ์ž์—ด ์ €์žฅ

Trie Principle

Trie Search

  1. ๊ฐ ๋…ธ๋“œ๊ฐ€ ๋ฐฐ์—ด๋กœ ๊ตฌ์„ฑ๋œ ํŠธ๋ฆฌ๋ฅผ ์ƒ์„ฑํ•œ๋‹ค.
  2. ์ €์žฅํ•˜๋ ค๋Š” ๋ฌธ์ž์—ด์˜ ๋ชจ๋“  ๋ฌธ์ž๋“ค์„ ํ™•์ธํ•˜๋ฉฐ ์•„๋ž˜ ๊ณผ์ •์„ ์‹œํ–‰ํ•œ๋‹ค.
  3. ๋ฃจํŠธ ๋…ธ๋“œ(๋ฌธ์ž ๋ฐฐ์—ด)์—์„œ ๋ฌธ์ž์—ด์˜ ์ฒซ๋ฒˆ์งธ ๋ฌธ์ž์— ํ•ด๋‹นํ•˜๋Š” ์ธ๋ฑ์Šค๋กœ ์ด๋™ํ•œ๋‹ค.
  4. ํ•ด๋‹น ์ธ๋ฑ์Šค์— ์—ฐ๊ฒฐ๋œ ์ž์‹ ๋…ธ๋“œ๊ฐ€ ์กด์žฌํ•˜์ง€ ์•Š๋Š”๋‹ค๋ฉด ์ƒˆ๋กœ์šด ๋…ธ๋“œ(๋ฌธ์ž ๋ฐฐ์—ด)๋ฅผ ํ• ๋‹นํ•œ๋‹ค. ์ดํ›„ ์ƒˆ๋กœ์šด ๋…ธ๋“œ์—์„œ ๋‘๋ฒˆ์งธ ๋ฌธ์ž์— ํ•ด๋‹นํ•˜๋Š” ์ธ๋ฑ์Šค๋กœ ์ด๋™ํ•œ๋‹ค.
  5. ํ•ด๋‹น ์ธ๋ฑ์Šค์— ์—ฐ๊ฒฐ๋œ ์ž์‹ ๋…ธ๋“œ๊ฐ€ ์กด์žฌํ•œ๋‹ค๋ฉด ํ•ด๋‹น ๋…ธ๋“œ์˜ ๋‘๋ฒˆ์งธ ๋ฌธ์ž์— ํ•ด๋‹นํ•˜๋Š” ์ธ๋ฑ์Šค๋กœ ์ด๋™ํ•œ๋‹ค.
  6. ๋ฌธ์ž์—ด์˜ ๋ชจ๋“  ๋ฌธ์ž๋ฅผ ๋‹ค ์ €์žฅํ•  ๋•Œ๊นŒ์ง€(์ฆ‰, ๋ฌธ์ž์—ด ๊ธธ์ด๋งŒํผ) ์œ„์˜ ๊ณผ์ •์„ ๋ฐ˜๋ณตํ•œ๋‹ค. ๋งˆ์ง€๋ง‰ ๋ฌธ์ž๋ฅผ ์ €์žฅํ•˜๊ณ  ๋‚˜์„œ๋Š” ๋ฐฐ์—ด ๊ฐ’์„ true๋กœ ์„ค์ •ํ•˜์—ฌ ํ•˜๋‚˜์˜ ๋ฌธ์ž์—ด์ด ์™„์ „ํžˆ ์ €์žฅ๋จ์„ ํ‘œ์‹œํ•œ๋‹ค.

์œ„์˜ ๊ณผ์ •์—์„œ ์ฃผ๋ชฉํ•  ์ ์€ ์ ‘๋‘์‚ฌ๊ฐ€ ๋™์ผํ•œ ๋ฌธ์ž์—ด์„ ์ €์žฅํ•  ๊ฒฝ์šฐ ์ตœ์†Œ ํ•˜๋‚˜ ์ด์ƒ์˜ ๋…ธ๋“œ๋ฅผ ๊ณต์œ ํ•œ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค!

ํŠธ๋ผ์ด์˜ ์‹œ๊ฐ„ ๋ณต์žก๋„

์œ„์˜ ๋ฐฉ์‹๋Œ€๋กœ ๋ฌธ์ž์—ด์„ ์ €์žฅํ•  ๊ฒฝ์šฐ ํ•œ ๋ฌธ์ž์—ด์„ ํƒ์ƒ‰ํ•  ๋•Œ ๊ณ ์ž‘ O(1)์˜ ์—ฐ์‚ฐ๋งŒ ํ•„์š”ํ•˜๊ฒŒ ๋œ๋‹ค.

์•„๋ฌด๋ฆฌ ํŠธ๋ฆฌ ๋…ธ๋“œ๊ฐ€ ๋งŽ์ด ์กด์žฌํ•˜๋”๋ผ๋„, ์‹ฌ์ง€์–ด๋Š” ์ „์„ธ๊ณ„ ๋ชจ๋“  ์ธ๊ตฌ์ธ 80์–ต๋ช…์˜ ์ด๋ฆ„์ด ์ €์žฅ๋œ ํŠธ๋ผ์ด๋ผ๊ณ  ํ• ์ง€๋ผ๋„, ์˜ค์ง O(1)์˜ ์‹œ๊ฐ„๋งŒ์ด ๊ฑธ๋ฆฐ๋‹ค. ๊ทธ ์ด์œ ๋Š” ํ•œ ๋ฌธ์ž์—ด์„ ํƒ์ƒ‰ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ํ•ด๋‹น ๋ฌธ์ž์—ด์ด ๊ฐ–๊ณ  ์žˆ๋Š” ๋ฌธ์ž ๋…ธ๋“œ๋งŒ์„ ํƒ์ƒ‰ํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ๋ฃจํŠธ ๋…ธ๋“œ์—์„œ๋ถ€ํ„ฐ ํ•ด๋‹น ๋ฌธ์ž์—ด์˜ ๊ธธ์ด ๋งŒํผ์˜ ์ž์‹ ๋…ธ๋“œ๋งŒ ํƒ€๊ณ  ๋“ค์–ด๊ฐ€๊ธฐ ๋•Œ๋ฌธ์—, ๋‹ค๋ฅธ ํƒ์ƒ‰ ์•Œ๊ณ ๋ฆฌ์ฆ˜๊ณผ ๋‹ฌ๋ฆฌ ์ €์žฅ๋œ ๋ฌธ์ž์—ด์˜ ๊ฐœ์ˆ˜์— ์˜ํ–ฅ์„ ๋ฐ›์ง€ ์•Š๋Š”๋‹ค๋Š” ์ ์ด ํŠธ๋ผ์ด์˜ ํฐ ํŠน์žฅ์ ์ด๋‹ค.

ํŠธ๋ผ์ด์˜ ๊ณต๊ฐ„ ๋ณต์žก๋„

์šฐ์ˆ˜ํ•œ ์‹œ๊ฐ„์  ์„ฑ๋Šฅ์„ ์ž๋ž‘ํ•˜๋Š” ํŠธ๋ผ์ด์˜ ์น˜๋ช…์ ์ธ ํ•œ๊ณ„๋Š” ๋ฐ”๋กœ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ๋งŽ์ด ์‚ฌ์šฉํ•œ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค.

ํŠธ๋ผ์ด๋ฅผ ์ด์šฉํ•ด ํ•œ๊ตญ์˜ 5์ฒœ๋งŒ ์ธ๊ตฌ์˜ ์ด๋ฆ„์„ ์ €์žฅํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ด๋ณด์ž. ํ•œ๊ตญ์—์„œ ๊ฐ€์žฅ ๊ธด ์ด๋ฆ„์€ "๋ฐ•ํ•˜๋Š˜๋ณ„๋‹˜๊ตฌ๋ฆ„ํ–‡๋‹˜๋ณด๋‹ค์‚ฌ๋ž‘์Šค๋Ÿฌ์šฐ๋ฆฌ"๋กœ 17์ž์ด๋‹ค. ์ด ์ด๋ฆ„์„ ์ €์žฅํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ํ•œ๊ธ€์˜ ๋ชจ๋“  ์Œ์ ˆ์„ ๋ฐฐ์—ด๋กœ ๋‹ด์€, ๊ธธ์ด๊ฐ€ 11,172์ธ ๋ฐฐ์—ด์ด 17๊ฐœ๊ฐ€ ํ•„์š”ํ•˜๊ณ  ์ด 189,924๋งŒํผ์˜ ๋ฉ”๋ชจ๋ฆฌ(1์Œ์ ˆ์„ 1byte๋กœ ๊ฐ€์ •)๊ฐ€ ํ•„์š”ํ•˜๋‹ค. ์ด๋ฆ„์˜ ๊ธธ์ด๊ฐ€ ๊ธธ์–ด์„œ ์ƒ๊ธด ๋ฌธ์ œ๋ผ๊ณ  ๋งํ•  ์ˆ˜๋„ ์žˆ๊ฒ ์ง€๋งŒ, ๊ฐ€์žฅ ๋ณดํŽธ์ ์ธ 3์ž ์ด๋ฆ„ ์—ญ์‹œ 11,172์ธ ๋ฐฐ์—ด์ด 3๊ฐœ๊ฐ€ ํ•„์š”ํ•˜๊ณ  ์ด 33,516๋งŒํผ์˜ ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ํ•„์š”ํ•˜๋‹ค. ํ•œ ๋ช…์˜ ์ด๋ฆ„์„ ์ €์žฅํ•˜๋Š”๋ฐ๋„ ์ด๋ ‡๊ฒŒ ๋งŽ์€ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜๋Š”๋ฐ ์ด๋Ÿฐ ๋ฐฉ์‹์œผ๋กœ 5์ฒœ๋งŒ๋ช…์˜ ์ด๋ฆ„์„ ์ €์žฅํ•œ๋‹ค๋ฉด ์–ด๋งˆ์–ด๋งˆํ•œ ํฌ๊ธฐ์˜ ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ํ•„์š”ํ•˜๊ฒŒ ๋  ๊ฒƒ์ด๋‹ค.(๋ฌผ๋ก  ๊ฐ™์€ ์„ฑ์„ ์‚ฌ์šฉํ•˜๊ฑฐ๋‚˜ ๋Œ๋ฆผ์ž๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์ด๋ฆ„์€ ๋…ธ๋“œ๋ฅผ ๊ฐ™์ด ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์–ด ์กฐ๊ธˆ์€ ํšจ์œจ์ ์ด๋ผ๊ณ  ๋งํ•  ์ˆ˜ ์žˆ๋‹ค.)

ํŠธ๋ผ์ด์˜ ๊ณต๊ฐ„ ๋ณต์žก๋„๋Š” ๋Œ€๋žต O(ํฌ์ธํ„ฐ ํฌ๊ธฐ * ํฌ์ธํ„ฐ ๋ฐฐ์—ด์˜ ๊ธธ์ด * ์ „์ฒด ๋…ธ๋“œ ๊ฐœ์ˆ˜)๊ฐ€ ๋œ๋‹ค. ๋”ฐ๋ผ์„œ ํŠธ๋ผ์ด๋Š” ์‹œ๊ฐ„์  ์„ฑ๋Šฅ๊ณผ ๊ณต๊ฐ„์  ์„ฑ๋Šฅ์„ ๋งž๋ฐ”๊พผ ๋Œ€ํ‘œ์ ์ธ ์˜ˆ๋กœ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

Java๋ฅผ ์ด์šฉํ•œ ํŠธ๋ผ์ด ๊ตฌํ˜„

class Trie {
    final int ALPHABET_SIZE = 26;         // ํฌ์ธํ„ฐ ๋ฐฐ์—ด์˜ ๊ธธ์ด(ํ‘œํ˜„ํ•  ์ˆ˜ ์žˆ๋Š” ๋ฌธ์ž ๊ฐœ์ˆ˜)

    class Node {
        Node[] children = new Node[ALPHABET_SIZE];     
        boolean isEndOfWord;              // ์ €์žฅํ•˜๋ ค๋Š” ๋ฌธ์ž์—ด์˜ ๋งˆ์ง€๋ง‰ ๋ฌธ์ž ์—ฌ๋ถ€

        public Node() {
            for (int i=0; i<ALPHABET_SIZE; i++) {
                children[i] = null;       // ํฌ์ธํ„ฐ ๋ฐฐ์—ด ์ดˆ๊ธฐํ™”
            }

            isEndOfWord = false;          // ๋งˆ์ง€๋ง‰ ๋ฌธ์ž ์—ฌ๋ถ€ ์ดˆ๊ธฐํ™”
        }
    }

    Node root;                            // ๋ฌธ์ž์—ด์˜ ์ฒซ๋ฒˆ์งธ ๋ฌธ์ž

    public void insert(String key) {
        int length = key.length();        // ํƒ์ƒ‰ํ•˜๋ ค๋Š” ๋ฌธ์ž์—ด ๊ธธ์ด
        int alphabetIdx;                  // ๋ฌธ์ž์—ด์˜ ๊ฐ ๋ฌธ์ž์˜ ์ธ๋ฑ์Šค
        Node curAlphabet = root;          // ํ˜„์žฌ ํƒ์ƒ‰์ค‘์ธ ๋ฌธ์ž์—ด์˜ ๋ฌธ์ž

        for (int level=0; level<length; level++) {
            alphabetIdx = key.charAt(level) - 'a';                    // ๋ฌธ์ž์—ด์˜ ๊ฐ ๋ฌธ์ž์˜ ์ธ๋ฑ์Šค ๊ตฌํ•˜๊ธฐ
            Node nextAlphabet = curAlphabet.children[alphabetIdx];    // ๋ฌธ์ž์—ด์˜ ๋‹ค์Œ ๋ฌธ์ž

            if (nextAlphabet == null) {         // ์ฐพ์œผ๋ ค๋Š” ๋ฌธ์ž์— ์—ฐ๊ฒฐ๋œ ์ž์‹ ๋…ธ๋“œ๊ฐ€ ์—†์„ ๊ฒฝ์šฐ
                nextAlphabet = new Node();      // ์ƒˆ๋กœ์šด ๋…ธ๋“œ ์ƒ์„ฑ ๋’ค ์ž์‹ ๋…ธ๋“œ๋กœ ์—ฐ๊ฒฐ
            }

            curAlphabet = nextAlphabet;         // ์ฐพ์œผ๋ ค๋Š” ๋ฌธ์ž์˜ ์ž์‹ ๋…ธ๋“œ๋ฅผ ํ˜„์žฌ ๋…ธ๋“œ๋กœ
        }

        curAlphabet.isEndOfWord = true;         // ๋ฌธ์ž์—ด์˜ ๋ชจ๋“  ๋ฌธ์ž์— ๋Œ€ํ•ด ์‚ฝ์ž…์ด ๋๋‚ฌ๋‹ค๋ฉด ๋งˆ์ง€๋ง‰ ๋ฌธ์ž์˜ ๋…ธ๋“œ๋Š” true๋กœ ๋ณ€๊ฒฝํ•˜์—ฌ ํ•˜๋‚˜์˜ ๋ฌธ์ž์—ด์ด ์ €์žฅ๋์Œ์„ ํ‘œ์‹œ
    }

    public boolean search(String key) {
        int length = key.length();        // ํƒ์ƒ‰ํ•˜๋ ค๋Š” ๋ฌธ์ž์—ด ๊ธธ์ด
        int alphabetIdx;                  // ๋ฌธ์ž์—ด์˜ ๊ฐ ๋ฌธ์ž์˜ ์ธ๋ฑ์Šค
        Node curAlphabet = root;          // ํ˜„์žฌ ํƒ์ƒ‰์ค‘์ธ ๋ฌธ์ž์—ด์˜ ๋ฌธ์ž

        for (int level=0; level<length; level++) {
            alphabetIdx = key.charAt(level) - 'a';
            Node nextAlphabet = curAlphabet.children[alphabetIdx];

            if (nextAlphabet == null) {         // ํƒ์ƒ‰ํ•˜๋ ค๋Š” ๋ฌธ์ž์—ด์ด ์กด์žฌํ•˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ
                return false;
            }

            curAlphabet = nextAlphabet;         // ์ฐพ์œผ๋ ค๋Š” ๋ฌธ์ž์˜ ์ž์‹ ๋…ธ๋“œ๋ฅผ ํ˜„์žฌ ๋…ธ๋“œ๋กœ
        }

        return (curAlphabet.isEndOfWord);       // ํƒ์ƒ‰ํ•˜๋ ค๋Š” ๋ฌธ์ž์—ด์ด ์กด์žฌํ•˜๋Š” ๊ฒฝ์šฐ
    }
}

ํŠธ๋ผ์ด์™€ ๋งต์˜ ์ฐจ์ด

  1. ํŠธ๋ผ์ด๋Š” ์ •๋ ฌ์„ ์ง€์›ํ•œ๋‹ค. (ํŠธ๋ฆฌ๋งต์€ ์ •๋ ฌ์„ ์ง€์›ํ•˜์ง€๋งŒ ํ•ด์‹œ๋งต์€ ์ง€์›ํ•˜์ง€ ์•Š์Œ)
  2. ํŠธ๋ผ์ด๋Š” ์ถฉ๋Œ์ด ๋ฐœ์ƒํ•˜์ง€ ์•Š๋Š”๋‹ค. (ํ•ด์‹œ๋งต์€ ๋ฐ์ดํ„ฐ๊ฐ€ ๋งŽ์„ ๊ฒฝ์šฐ ์ถฉ๋Œ์ด ๋ฐœ์ƒํ•  ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ์Œ)
  3. ํŠธ๋ผ์ด๋ฅผ ํ™œ์šฉํ•ด ํƒ์ƒ‰ํ•  ๊ฒฝ์šฐ ๋งต๋ณด๋‹ค ์‹œ๊ฐ„์  ์„ฑ๋Šฅ์ด ์ข‹์„ ์ˆ˜ ์žˆ๋‹ค. (ํŠธ๋ฆฌ๋งต์˜ ๊ฒฝ์šฐ ์ด์ง„ ๊ฒ€์ƒ‰ ํŠธ๋ฆฌ ํ˜•ํƒœ์ด๋ฏ€๋กœ ํƒ์ƒ‰ ์‹œ๊ฐ„ ๋ณต์žก๋„๊ฐ€ O(logN) ์ž„)
  4. ํŠธ๋ผ์ด๊ฐ€ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ๋” ๋งŽ์ด ์‚ฌ์šฉํ•œ๋‹ค.