1. 程式人生 > >Trie字典樹模板及栗子

Trie字典樹模板及栗子

模板

Trie字典樹大致可以分為兩種實現方式,一種是陣列,另一種是指標,那麼我們就整理了兩個模板:

陣列的實現:

#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <map>
using namespace std;
const int N = 1000000;
int ch[N][26],val[N],tot;
//陣列實現的話,總是拿不準ch陣列的大小,我們不確定生成的節點會有多少
void Init()
{
    memset(ch[0],0,sizeof(ch[0]));
    tot = 1;
    memset(val,0,sizeof(val));
}


void Insert(char *s,int x)
{
    int u = 0,len = strlen(s);
    for(int i =0 ;i < len;i ++)
    {
        int v = s[i]-'a';
        if(!ch[u][v])
        {
            memset(ch[tot],0,sizeof(ch[tot]));
            val[tot] = 0;
            ch[u][v] = tot ++;
        }
        u = ch[u][v];
    }
    val[u] = x;//結尾位置設定為權重,其餘位置都設定為0
}


int Find(char *s)
{
    int u = 0,len = strlen(s);
    for(int i =0;i < len;i ++)
    {
        int v = s[i]-'a';
        if(!ch[u][v]) return 0;
        u = ch[u][v];
    }
    return val[u];
}


void Del(char  *s)
{
    int  u = 0,len = strlen(s);
    for(int i =0 ;i < len;i ++)
    {
        int v = s[i] - 'a';
        if(!ch[u][v]) return ;
        u = ch[u][v];
    }
    val[u] = 0;//刪除時就是將最後一個位置的權值設定為0
}

指標實現

#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <map>
using namespace std;
//指標實現較為方便,並且也很容易理解
struct Trie
{
    Trie *next[26];
    int val;
};
Trie *root;
void Init()
{
    root = (Trie *)malloc(sizeof(Trie));
    for(int i = 0;i < 26;i ++)
        root->next[i] = NULL;
    root->val = 0;
}
void Insert(char *s)
{
    Trie *p = root,*q;
    int len = strlen(s);
    for(int i = 0;i < len;i ++)
    {
        int v = s[i] - 'a';
        if(p->next[v] == NULL)
        {
            q = (Trie *)malloc(sizeof(Trie));
            q->val = 0;
            for(int j = 0;j < 26;j ++)
                q->next[j] = NULL;
            p->next[v] = q;
        }
        p = p->next[v];
    }
    p->val = 1;
}

int Find(char *s)
{
    int len = strlen(s);
    Trie *p = root;
    for(int i =0 ;i < len;i ++)
    {
        int v = s[i] - 'a';
        p = p->next[v];
        if(p == NULL)  return -1;
    }
    return p->val;
}

void Del(Trie *s)
{
    if(s == NULL)
        return ;
    for(int i =0;i < 26;i ++)
        if(s->next[i])
            Del(s->next[i]);
    delete s;
}

栗子

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
#include<cmath>

using namespace std;
const int N = 1000000;
int sz;
int ch[N][26];
int val[N];
struct Trie
{
    Trie(){
        sz = 1;//這裡要把0節點空出來,作為全部的根節點
        memset(ch[0],0,sizeof(ch[0]));
        memset(val,0,sizeof(val));
    }

    int idx(char c)
    {
        return c-'a';
    }
    void Insert(char *s,int v)
    {
        int u = 0,len = strlen(s);
        for(int i =0 ;i < len;i ++)
        {
            int c = idx(s[i]);
            if(!ch[u][c])//表示這個節點重新作為一個新的節點,下面仍然還有26個子節點
            {
                memset(ch[sz],0,sizeof(ch[sz]));
                val[sz] = 0;
                ch[u][c] = sz++;
            }
            u = ch[u][c];
            val[u] ++;
        }
    }
    int Read(char *s)
    {
        int u = 0,len = strlen(s);
        for(int i = 0;i < len;i ++)
        {
            int c = idx(s[i]);
            if(!ch[u][c])  return -1;
            else  u = ch[u][c];
        }
        if(val[u] == 0)
            return 1;
        else
            return 2;
    }
    int Get_num(char *s)
    {
        int u = 0,len = strlen(s);
        for(int i = 0;i < len;i ++)
        {
            int c = idx(s[i]);
            if(!ch[u][c]) return 0;
            else u = ch[u][c];
        }
        return val[u];
    }
};

int main()
{
    Trie T;
    char s[15];
    while(1)
    {
        gets(s);
        if(s[0] == '\0') break;
        T.Insert(s,1);
    }
    while(gets(s))
    {
        printf("%d\n",T.Get_num(s));
    }
    return 0;
}
#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <map>
using namespace std;
struct Trie
{
    Trie *next[26];
    char *val;
};
Trie *root;
void Init()
{
    root = (Trie *)malloc(sizeof(Trie));
    for(int i = 0;i < 26;i ++)
        root->next[i] = NULL;
    root->val = NULL;
}
void Insert(char *s,char *str)
{
    Trie *p = root,*q;
    int len = strlen(s);
    for(int i = 0;i < len;i ++)
    {
        int v = s[i] - 'a';
        if(p->next[v] == NULL)
        {
            q = (Trie *)malloc(sizeof(Trie));
            q->val = NULL;
            for(int j = 0;j < 26;j ++)
                q->next[j] = NULL;
            p->next[v] = q;
        }
        p = p->next[v];
    }
    p->val = new char[11];
    strcpy(p->val,str);
}

void Find(char *s)
{
    int len = strlen(s);
    Trie *p = root;
    for(int i =0 ;i < len;i ++)
    {
        int v = s[i] - 'a';
        p = p->next[v];
        if(p == NULL)  {printf("%s",s);return ;}
    }
    if(p->val)  printf("%s",p->val);
    else printf("%s",s);
}

void Del(Trie *s)
{
    if(s == NULL)
        return ;
    for(int i =0 ;i < 26;i ++)
    {
        if(s->next[i])
            Del(s->next[i]);
    }
    delete s->val;
    delete s;
}

int main()
{
    char s[15],s1[15];
    Init();
    scanf("%s",s);
    while(scanf("%s %s\n",s,s1) && strcmp(s,"END"))
    {
        Insert(s1,s);
    }
    char str[3100],part[100];
    while(gets(str) && strcmp(str,"END"))
    {
        int index = 0;
        int len = strlen(str);
        for(int i = 0;i < len;i ++)
        {
            if(islower(str[i]))
                part[index++] = str[i];
            else
            {
                part[index] = '\0';
                Find(part);
                index = 0;
                printf("%c",str[i]);
            }
        }
        puts("");
    }
}

參考部落格

相關推薦

Trie字典模板栗子

模板Trie字典樹大致可以分為兩種實現方式,一種是陣列,另一種是指標,那麼我們就整理了兩個模板:陣列的實現:#include <iostream> #include <cstdio> #include <string> #include &

字典模板例題

(一)Trie的簡介 Trie樹,又稱字典樹,單詞查詢樹或者字首樹,是一種用於快速檢索的多叉樹結構,如英文字母的字典樹是一個26叉樹,數字的字典樹是一個10叉樹。他的核心思想是空間換時間,空間消耗大但是插入和查詢有著很優秀的時間複雜度。 (二)Trie的定義 Trie

字典模板

nbsp spa else space iostream ins out ring eat #include<iostream> #include<string> using namespace std; //表示next數組的長度,表示26個

Trie 字典

src spa main ets strcmp() ems next arc ear 1、UVa 1401 Remember the Word   題意:給出n個字符串集合,問其有多少種組合方式形成目標字符串。   思路:對n個字符串集合建立Trie樹,保存每個結點的字

bzoj3261: 最大異或和 可持久化字典模板

roo CP 前綴和 sum oot 可持久化 可持久化字典樹 == tdi 可持久化字典樹不過記得是兩次前綴和,所以記得減2,還有p=1的情況。 #include<bits/stdc++.h> using namespace std; int l[18000

CH 1601 - 字首統計 - [字典模板題]

題目連結:傳送門 描述給定 $N$ 個字串 $S_1,S_2,\cdots,S_N$,接下來進行 $M$ 次詢問,每次詢問給定一個字串 $T$,求 $S_1 \sim S_N$ 中有多少個字串是 $T$ 的字首。輸入字串的總長度不超過 $10^6$,僅包含小寫字母。 輸入格式第一行兩個整數 $N,M$。接

字典模板題 Shortest Prefixes

B - Shortest Prefixes Time Limit:1000MS     Memory Limit:30000KB     Description A prefix of a string is

字典模板題(統計難題 HDU - 1251)

https://vjudge.net/problem/HDU-1251 標準的字典樹模板題: 也注意一下輸入方法: #include<iostream> #include<cstdio> #include<cstring> using namespace std

字典模板(有待更新,連結串列版)

連結串列版:空間小,時間大。 陣列版:空間大,時間小 struct node { int num; node *next[maxn]; }; //字典樹 class Tree{ public: node *head; //建構函式 Tree() {

poj--3630 Phone List(Trie字典

3630-Phone List Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 34575 Accepted: 9924 Description Given a l

hdu1251(字典模板

#include<bits/stdc++.h> using namespace std; typedef long long LL; const int maxn=2000000+10; c

HDU1251字典模板

Problem Description Ignatius最近遇到一個難題,老師交給他很多單詞(只有小寫字母組成,不會有重複的單詞出現),現在老師要他統計出以某個字串為字首的單詞數量(單詞本身也是自己的字首).     Input 輸入資料的第一部分是一張

Trie字典

本來刷dp刷得好好的…突然要講…那就學學吧 以下為兩種寫法 桶儲存 : 空間換取時間 深度作為字串長度,每個元素作為一個長度為26的桶,每個的下標代表相應字母的序號,存下一個元素的id 具體實現虛擬碼

1671 Phone List (字典模板

Given a list of phone numbers, determine if it is consistent in the sense that no number is the prefix of another. Let’s say the phone cat

資料結構——Trie 字典 字首

一、什麼是Trie Trie不同於二分搜尋樹、堆、線段樹等二叉樹結構,Trie是一個多叉樹。使用場景:通訊錄高效搜尋,專為處理字串設計的。 比如字典中有n條資料,如果使用樹結構,查詢的時間複雜度是O(logn),如果有100萬條資料的話,logn大約是20,如果有1億

字典模板題 Shortest Prefixes

B - Shortest Prefixes Time Limit:1000MS     Memory Limit:30000KB     Description A prefix of a string is a substring starting at the be

字典模板(陣列實現和指標實現)

///這裡以輸入字串後,查詢字串出現的次數為例#include<bits/stdc++.h>#define MAX 26using namespace std;typedef struct TrieNode           ///Trie節點宣告{     int  num;         

HDU 4825 Xor Sum 01字典模板

題目連結 思路 01字典樹模板題,將所有數從高位開始插入到樹中。 #include<cstdio> #include<iostream> #include<a

poj 3630 / hdu 1671 Phone List 【Trie字典 動態建立&靜態建立】

Phone List Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 25160 Accepted: 7641 Description Given a list of phone numb

HDU4825 01字典模板

題解:    第一次知道字典樹還能這樣用,果然還是做題太少了。。ORZ,感覺很多異或的題都可以用字典樹去解決#include<stdio.h> #include<string.h> #include<algorithm> using nam