zoukankan      html  css  js  c++  java
  • 字典树

    代码实现

    Java

    packagecom.suning.search.test.tree.trie;

    public class Trie{
    private int SIZE=26;
    private TrieNode root;//字典树的根

    Trie(){//初始化字典树 
    root=new TrieNode();
    }

    private class TrieNode{//字典树节点
    private int num;//有多少单词通过这个节点,即节点字符出现的次数
    private TrieNode[]  son;//所有的儿子节点
    private boolean isEnd;//是不是最后一个节点
    private char val;//节点的值

    TrieNode(){
    num=1;
    son=new TrieNode[SIZE];
    isEnd=false;
    }
    }

    //建立字典树
    public void insert(String str){//在字典树中插入一个单词
    if(str==null||str.length()==0){
    return;
    }
    TrieNode node=root;
    char[]letters=str.toCharArray();
    for(inti=0,len=str.length();i<len;i++){
    int pos=letters[i]-'a';
    if(node.son[pos]==null){
    node.son[pos]=newTrieNode();
    node.son[pos].val=letters[i];
    }else{
    node.son[pos].num++;
    }
    node=node.son[pos];
    }
    node.isEnd=true;
    }

    //计算单词前缀的数量
    public int countPrefix(Stringprefix){
    if(prefix==null||prefix.length()==0){
    return-1;
    }
    TrieNode node=root;
    char[]letters=prefix.toCharArray();
    for(inti=0,len=prefix.length();i<len;i++){
    int pos=letters[i]-'a';
    if(node.son[pos]==null){
    return 0;

    else{
    node=node.son[pos];
    }
    }
    return node.num;
    }
    //打印指定前缀的单词
    public String hasPrefix(String prefix) {
        if (prefix == null || prefix.length() == 0) {
            return null;
        }
        TrieNode node = root;
        char[] letters = prefix.toCharArray();
        for (int i = 0, len = prefix.length(); i < len; i++) {
            int pos = letters[i] - 'a';
            if (node.son[pos] == null) {
                return null;
            } else {
                node = node.son[pos];
            }
        }
        preTraverse(node, prefix);
        return null;
    }
    // 遍历经过此节点的单词.
    public void preTraverse(TrieNode node, String prefix) {
        if (!node.isEnd){
            for (TrieNode child : node.son) {
                if (child!=null){
                    preTraverse(child, prefix+child.val);
                }
            }
            return;
        }
        System.out.println(prefix);
    }


    //在字典树中查找一个完全匹配的单词.
    public boolean has(Stringstr){
    if(str==null||str.length()==0){
    return false;
    }
    TrieNode node=root;
    char[]letters=str.toCharArray();
    for(inti=0,len=str.length();i<len;i++){
    intpos=letters[i]-'a';
    if(node.son[pos]!=null){
    node=node.son[pos];
    }else{
    return false;
    }
    }
    return node.isEnd;
    }

    //前序遍历字典树.
    public void preTraverse(TrieNodenode){
    if(node!=null){
    System.out.print(node.val+"-");
    for(TrieNodechild:node.son){
    preTraverse(child);
    }
    }
    }

    public TrieNode getRoot(){
    return this.root;
    }

    public static void main(String[]args){
    Trietree=newTrie();
    String[]strs={"banana","band","bee","absolute","acm",};
    String[]prefix={"ba","b","band","abc",};
    for(Stringstr:strs){
    tree.insert(str);
    }
    System.out.println(tree.has("abc"));
    tree.preTraverse(tree.getRoot());
    System.out.println();
    //tree.printAllWords();
    for(Stringpre:prefix){
    int num=tree.countPrefix(pre);
    System.out.println(pre+""+num);
    }
    }
    }

    C语言

    #define MAX 26//字符集大小
    typedef struct TrieNode
    {
        int nCount;//记录该字符出现次数
        struct TrieNode* next[MAX];
    }TrieNode;

    TrieNode Memory[1000000];
    int allocp=0;

    /*初始化*/
    void InitTrieRoot(TrieNode* *pRoot)
    {
        *pRoot=NULL;
    }

    /*创建新结点*/
    TrieNode* CreateTrieNode()
    {
        int i;
        TrieNode *p;
        p=&Memory[allocp++];
        p->nCount=1;
        for(i=0;i<MAX;i++)
        {
            p->next[i]=NULL;
        }
        return p;
    }

    /*插入*/
    void InsertTrie(TrieNode* *pRoot,char *s)
    {
        inti,k;
        TrieNode*p;
        if(!(p=*pRoot))
        {
            p=*pRoot=CreateTrieNode();
        }
        i=0;
        while(s[i])
        {
            k=s[i++]-'a';//确定branch
            if(!p->next[k])
                p->next[k]=CreateTrieNode();
                    p->next[k]->nCount++;
            p=p->next[k];
        }
    }

    //查找
    int SearchTrie(TrieNode* *pRoot,char *s)
    {
        TrieNode *p;
        int i,k;
        if(!(p=*pRoot))
        {
            return0;
        }
        i=0;
        while(s[i])
        {
            k=s[i++]-'a';
            if(p->next[k]==NULL) return 0;
            p=p->next[k];
        }
        return p->nCount;
    }

    C++

    #include<cstring>
    #include<iostream>
    #include<conio.h>
    usingnamespacestd;
    namespacetrie
    {
    template<classT,size_tCHILD_MAX>
    /*
    ParameterT:Typeofreserveddata.
    ParameterCHILD_MAX:Sizeofarryofpointerstochildnode.
    */
    structnod
    {
    Treserved;
    nod<T,CHILD_MAX>*child[CHILD_MAX];
    nod()
    {
    memset(this,0,sizeof*this);
    }
    ~nod()
    {
    for(unsignedi=0;i<CHILD_MAX;i++)
    deletechild[i];
    }
    voidTraversal(char*str,unsignedindex)
    {
    unsignedi;
    for(i=0;i<index;i++)
    cout<<str[i];
    cout<<' '<<reserved<<endl;
    for(i=0;i<CHILD_MAX;i++)
    {
    if(child[i])
    {
    str[index]=i;
    child[i]->Traversal(str,index+1);
    }
    }
    return;
    }
    };

    template<classT,size_tCHILD_MAX=127>
    /*
    ParameterT:Typeofreserveddata.
    ParameterCHILD_MAX:Sizeofarryofpointerstochildnode.
    */
    classtrie
    {
    private:
    nod<T,CHILD_MAX>root;
    public:
    nod<T,CHILD_MAX>*AddStr(char*str);
    nod<T,CHILD_MAX>*FindStr(char*str);
    boolDeleteStr(char*str);
    voidTraversal()
    {
    charstr[100];
    root.Traversal(str,0);
    }
    };

    template<classT,size_tCHILD_MAX>
    nod<T,CHILD_MAX>*trie<T,CHILD_MAX>::AddStr(char*str)
    {
    nod<T,CHILD_MAX>*now=&root;
    do
    {
    if(now->child[*str]==NULL)
    now->child[*str]=newnod<T,CHILD_MAX>;
    now=now->child[*str];
    }while(*(++str)!='');
    returnnow;
    }

    template<classT,size_tCHILD_MAX>
    nod<T,CHILD_MAX>*trie<T,CHILD_MAX>::FindStr(char*str)
    {
    nod<T,CHILD_MAX>*now=&root;
    do
    {
    if(now->child[*str]==NULL)
    returnNULL;
    now=now->child[*str];
    }while(*(++str)!='');
    returnnow;
    }

    template<classT,size_tCHILD_MAX>
    booltrie<T,CHILD_MAX>::DeleteStr(char*str)
    {
    nod<T,CHILD_MAX>**nods=newnod<T,CHILD_MAX>*[strlen(str)];
    intsnods=1;
    nod<T,CHILD_MAX>*now=&root;
    nods[0]=&root;
    do
    {
    if(now->child[*str]==NULL)
    returnfalse;
    nods[snods++]=now=now->child[*str];
    }while(*(++str)!='');
    snods--;
    while(snods>0)
    {
    for(unsignedi=0;i<CHILD_MAX;i++)
    if(nods[snods]->child[i]!=NULL)
    returntrue;
    deletenods[snods];
    nods[--snods]->child[*(--str)]=NULL;
    }
    returntrue;
    }
    }
    intmain()
    {
    //TestProgram
    trie::trie<int>tree;
    while(1)
    {
    cout<<"1foraddastring"<<endl;
    cout<<"2forfindastring"<<endl;
    cout<<"3fordeleteastring"<<endl;
    cout<<"4fortraversal"<<endl;
    cout<<"5forexit"<<endl;
    charstr[100];
    switch(getch())
    {
    case'1':
    cin.getline(str,100);
    cout<<"Thisstinghasexistedfor"<<tree.AddStr(str)->reserved++<<"times."<<endl;
    break;
    case'2':
    cin.getline(str,100);
    trie::nod<int,127>*find;
    find=tree.FindStr(str);
    if(!find)
    cout<<"Nofound."<<endl;
    else
    cout<<"Thisstinghasexistedfor"<<find->reserved<<"times."<<endl;
    break;
    case'3':
    cin.getline(str,100);
    cout<<"Theactionis"<<(tree.DeleteStr(str)?"Successful.":"Unsuccessful.")<<endl;
    break;
    case'4':
    tree.Traversal();
    break;
    case'5':
    return0;
    }
    }
    return0;
    }
  • 相关阅读:
    超详细的java生成excel文件并下载
    springboot 单元测试
    git常用操作命令
    mac终端指定应用程序打开文件、文件夹
    map常用遍历方法
    视图、存储过程和函数(二)
    视图、存储过程和函数(一)
    protobuf安装旧版本(适用于mac)
    mac常用快捷键
    MySQL 中的坑
  • 原文地址:https://www.cnblogs.com/developer-ios/p/5326803.html
Copyright © 2011-2022 走看看