데이터 구조 시리즈 - 트 리
트 리 구조
Trie 의 핵심 사상 은 공간 교환 시간 이다. 문자열 의 공공 접 두 사 를 이용 하여 조회 시간의 비용 을 낮 추어 효율 을 높이 는 목적 을 달성 하 는 것 이다.
예 를 들 어 tea, ten, to, in, inn, int 라 는 단 어 를 하나의 Trie 나무 로 구축 하고 구체 적 인 Tried 나무의 구 조 를 살 펴 보 자.
그림: 트 리 구조
그림 에서 트 리 의 일부 특성 을 볼 수 있다.
트 리 구현
Trie 트 리 의 삽입, 삭제, 찾기 동작 은 모두 같 습 니 다. 트 리 를 간단하게 한 번 옮 겨 다 니 면 됩 니 다. 시간 복잡 도: O (n) (n 은 문자열 의 길이).Tried 트 리 의 실현 은 배열 과 링크 두 가지 방식 을 사용 할 수 있 습 니 다.
다음은 가장 간단 한 트 리 트 리 의 실현 으로 배열 방식 을 사용한다.
/**
 * 
 *     Trie   ,    Trie    ,         
 * 
 *
 * @author Vicky
 * @email [email protected]
 * @2015 11 23 
 *
 */
public class Trie {
    protected TrieNode root = new TrieNode('a');// TrieTree    
    /**
     *   
     * 
     * @param word
     */
    public void insertWord(String word) {
        TrieNode index = this.root;
        for (char c : word.toLowerCase().toCharArray()) {
            index = index.addChild(c);
        }
        return;
    }
    /**
     * TrieTree   
     */
    private class TrieNode {
        /**        */
        private final char nodeChar;//
        /**   TrieTree        */
        private TrieNode[] childNodes = null;
        public TrieNode(char nodeChar) {
            super();
            this.nodeChar = nodeChar;
        }
        public TrieNode addChild(char ch) {
            int index = ch - 'a';
            if (null == childNodes) {
                this.childNodes = new TrieNode[26];
            }
            if (null == childNodes[index]) {
                childNodes[index] = new TrieNode(ch);
            }
            return childNodes[index];
        }
        @Override
        public String toString() {
            return "TrieNode [nodeChar=" + nodeChar + "]";
        }
    }
    public static void main(String[] args) {
        Trie trie = new Trie();
        trie.insertWord("Vicky");
    }
}Trie 트 리 응용
Trie 트 리 의 응용 은 주로 문자열 처리 에 집중 되 어 있 습 니 다.(1) 문자열 검색
(2) 최 장 공공 접두사
다음은 트 리 트 리 의 응용 에 대해 상대 적 으로 간단 하고 대표 적 인 사례 를 선택 하 겠 습 니 다. 한 단어 에서 'vi' 로 시작 하 는 모든 문자열 을 찾 고 'Vicky' 가 나 타 났 는 지 확인 하 겠 습 니 다.(우 리 는 26 글자 만 저장 하기 때문에 대소 문 자 를 구분 하지 않 고 단어 가 아 닌 문 자 를 지원 하지 않 습 니 다.)
인터넷 에서 다음 단어 표를 다운로드 하고 단어 표 에 따라 트 리 트 리 를 구축 하고 찾 을 수 있 습 니 다. 단어 표 는https://github.com/dwyl/english-words다운 로드 를 진행 하 다.
package com.vicky.datastructure.tree.trie;
/**
 * 
 *                Trie 
 * 
 *
 * @author Vicky
 * @email [email protected]
 * @2015 11 23 
 *
 */
public class PrefixTrie {
    private TrieNode root = new TrieNode('a');// TrieTree    
    /**
     *   
     * 
     * @param word
     */
    public void insertWord(String word) {
        TrieNode index = this.root;
        for (char c : word.toLowerCase().toCharArray()) {
            index = index.addChild(c);
            index.addPrefixCount();
        }
        index.addCount();
        return;
    }
    /**
     *   
     * 
     * @param word
     * @return
     */
    public boolean selectWord(String word) {
        TrieNode index = this.root;
        for (char c : word.toLowerCase().toCharArray()) {
            index = index.getChild(c);
            if (null == index) {
                return false;
            }
        }
        return index.getCount() > 0;
    }
    /**
     *          
     * 
     * @param prefix
     * @return
     */
    public int selectPrefixCount(String prefix) {
        TrieNode index = this.root;
        for (char c : prefix.toLowerCase().toCharArray()) {
            index = index.getChild(c);
            if (null == index) {
                return 0;
            }
        }
        return index.getPrefixCount();
    }
    /**
     * TrieTree   
     */
    private class TrieNode {
        /**        */
        private final char nodeChar;//
        /**   TrieTree        */
        private TrieNode[] childNodes = null;
        private int count = 0;//     ,            
        private int prefixCount = 0;//     ,            
        public TrieNode(char nodeChar) {
            super();
            this.nodeChar = nodeChar;
        }
        public TrieNode addChild(char ch) {
            int index = ch - 'a';
            if (null == childNodes) {
                this.childNodes = new TrieNode[26];
            }
            if (null == childNodes[index]) {
                childNodes[index] = new TrieNode(ch);
            }
            return childNodes[index];
        }
        public TrieNode getChild(char ch) {
            int index = ch - 'a';
            if (null == childNodes || null == childNodes[index]) {
                return null;
            }
            return childNodes[index];
        }
        public void addCount() {
            this.count++;
        }
        public int getCount() {
            return this.count;
        }
        public void addPrefixCount() {
            this.prefixCount++;
        }
        public int getPrefixCount() {
            return this.prefixCount;
        }
        @Override
        public String toString() {
            return "TrieNode [nodeChar=" + nodeChar + "]";
        }
    }
}
package com.vicky.datastructure.tree.trie;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.regex.Pattern;
import org.junit.Before;
import org.junit.Test;
public class TrieUsedTest {
    private PrefixTrie trie;
    @Before
    public void before() throws IOException {
        Pattern pattern = Pattern.compile("[a-zA-Z]+");
        //         ,  TriedTree
        InputStreamReader read = new InputStreamReader(this.getClass().getResourceAsStream("words.txt"));
        BufferedReader reader = new BufferedReader(read);
        trie = new PrefixTrie();
        String line = null;
        while (null != (line = reader.readLine())) {
            line = line.trim();
            if (!pattern.matcher(line).matches()) {//       ,   “-”
                continue;
            }
            trie.insertWord(line);
        }
    }
    /**
     *     TriedTree         
     */
    @Test
    public void searchPrefixWords() {
        String prefix = "vi";
        System.out.println(trie.selectPrefixCount(prefix));
        System.out.println(trie.selectWord("Vicky"));
    }
}
코드 에서 정확 한 검색 과 접 두 사 를 찾 는 두 가지 방식 을 지원 하기 위해 저 희 는 TrieNode 를 수정 하여
private int count = 0;private int prefixCount = 0; 두 개의 변 수 를 추 가 했 습 니 다. 각각 단어 가 나타 나 는 횟수 와 접두사 가 나타 나 는 횟수 를 저장 하 는 데 사 용 됩 니 다.테스트 결 과 는 텍스트 편집 기 를 사용 하여 대 비 를 찾 을 수 있 습 니 다.트 리 트 리 의 응용 장면 에 대해 서 는 참고 글 1 을 읽 을 수 있 습 니 다.
참고 문장
데이터 구조의 트 리 트 리 는 트 리 (사전 트 리) 에서 접미사 트 리 (10.28 수정) 까지 6 일 동안 트 리 구 조 를 통식 합 니 다. 5 일 째 트 리 입 니 다.
저의 개인 블 로그 에 오신 것 을 환영 합 니 다. 더 많은 즐거움 을 찾 으 세 요 ~
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
정수 반전Udemy 에서 공부 한 것을 중얼거린다 Chapter3【Integer Reversal】 (예) 문자열로 숫자를 반전 (toString, split, reverse, join) 인수의 수치 (n)가 0보다 위 또는 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.