Trie []

Outline

    Dictionary tree , also known as trie , Trie tree is a tree structure , a variation on the hash tree. Typical applications for statistics, sort and save a lot of strings (strings, but not limited to), it is often used for text search engine system word frequency statistics. Its advantages are: the use of a common prefix string to reduce the query time, minimizing unnecessary string comparison, high efficiency Bi Haxi query tree. (Quoted from Baidu Encyclopedia "trie")

He said light understand, the cases cited -

NKOJ 1934 foreigners

    You admitted to the big city Shapingba school, but Shapingba locals speaks a dialect is difficult to understand, you totally
do not understand. Fortunately, your hands have this dictionary can help you. Now you have several did not understand the need to query the dialect dictionary.
Input format :
The first line, two integers n and m.
Then there are n lines representing the contents of the dictionary, each row represents a record dictionary. Each record contains two space-separated words, a word for the first English word, the second word corresponding Shapingba dialect.
Then there are m rows, one word per line, represents Shapingba dialect you want to query.
Output Format :
Output m rows, each row an English word, represents the result of translation.
If you can not find a word dictionary, the output of "eh"
Sample input :
5 3
Dog ogday
CAT atcay
Pig igpay
Froot ootfray
Loops oopslay
atcay
ittenkay
oopslay
sample output :
CAT
EH
Loops
 Note: all words in lowercase letters, and length of not more than 10.
Portal : http://oi.nks.edu.cn/zh/Problem/Details/1934

Trie Tree features

  1. The root node does not include characters, each node except the root node contains only one character.

  2. From the root node to a node on the path through the connected characters, the string corresponding to that node.

  3. Find the number of nodes in a tree key time and has nothing contained in trie tree, depending on the number of characters and keywords. That is, to find the string s time O (s.length ())

  4. To find keywords can be decomposed into a sequence of characters and not very long, using the Trie search speed than a binary search tree.
  Such as: If the maximum key length is 5, the use of the Trie, using 5 from comparison 26 is 5 = 11,881,376 possible keywords specified in the retrieved keyword. The use of a binary search tree to be at least log 2 265 = 23.5 comparisons.

Examples solution to give the following primers main function portion (not shown partially initialized) -
struct node {
    int Num; //如果该节点是一个单词的结尾,记录对应单词的编号 int Next[26]; //儿子节点的编号 }trie[1000001]; string s[100001], a; int main() { cin >> n >> m; for (k = 1; k <= n; k ++){ cin >> s[k] >> a; Insert(a, k); } for (k = 1; k <= m; k ++) { cin >> a; ans = Find(a); if (ans)cout << s[ans]; else cout << "eh" << endl; } return 0; }
Followed by a two part function -
void Insert(string c, int k) {
    int i, t, len, p = 1; len = c.length(); for (i = 0; i < len; i ++) { t = c[i] - 'a';//将字符c[i]转换成值为0到25的数字,比如'a'转换为0,'b'转换为1,‘c’转换为2…… if (trie[p].Next[t] == 0) { //若p没有值为t的儿子 tot ++; //新增一个编号为tot的节点 trie[p].Next[t] = tot; //记下p的值为t的孩子节点的编号 p = trie[p].Next[t]; //p指向新添加的节点 trie[p].Num = 0; //初始化新添加的节点,将其标记为不是单词的结尾 } else p = trie[p].Next[t]; //若p存在值为t的儿子,p指向该儿子,继续讨论 } trie[p].Num = k; //for循环已执行完,说明第k个单词已加入,在单词结尾做上标记 } 

int Find(string c) {
    int i, t, len, p = 1; len = c.length(); for (i = 0; i < len; i ++) { t = c[i] - 'a'; if (trie[p].Next[t] == 0)return 0; //当前要匹配值为t的字母,若没有则结束 p = trie[p].Next[t]; //若存在值为t的字母,则继续匹配 } return trie[p].Num; //若for循环执行完毕,说明找到了需要的单词,返回其编号 }
The above code is almost a template trie, in a different title in the main function may be different, you can familiarize yourself with the principle whereby trie, and then modify as appropriate.

the trie simple question:

So he named the wrong P2580 started

#include<bits/stdc++.h>
using namespace std;
int tot,n,m;
string s;
struct node{
    int num,nxt[30];
}trie[1000005];
map<string,int>mp,mpp;
int Insert(string ss,int k){
    int p=1,len=ss.length();
    for(int i=0;i<len;i++){
        int t=ss[i]-'a';
        if(trie[p].nxt[t]==0){
            tot++;
            p=trie[p].nxt[t]=tot;
            trie[p].num=0;
        }
        else p=trie[p].nxt[t];
    }
    trie[p].num=k;
}
int myfind(string ss)
{
    int len=ss.length();
    int p=1;
    for(int i=0;i<len;i++){
        int t=ss[i]-'a';
        if(trie[p].nxt[t]==0) return 0;
        p=trie[p].nxt[t];
    }
    return 1;
}
int main()
{
    cin>>n;
    for(int i=1;i<=n;i++){
        cin>>s;
        Insert(s,i);
    }
    cin>>m;
    for(int i=1;i<=m;i++){
        cin>>s;
        if(myfind(s)==0) cout<<"WRONG"<<endl;
        else if(myfind(s)&&mpp[s]==0) {cout<<"OK"<<endl;mpp[s]++;}
        else cout<<"REPEAT"<<endl;
    }
}

  NKOJ 1931 phone book

#include <the iostream>   
#include <CString> 
#include <cstdio>   
the using namespace STD; 
const int = 100005 MAXN, maxnode = 200005; 
int n-; 
BOOL OK; 
struct Node { 
	int NUM, Next [10]; 
}; 
struct Trie { 
	int size; 
	String S [MAXN]; 
	Node Trie [MAXN]; 
	void SET () { 
		size =. 1; 
		Memset (Trie, 0, the sizeof (Trie)); 
	} 
	int IDX (char X) {return (int) X -'0 ';} 
	BOOL INSERT (a String, int ID) { 
		int I, P =. 1, T, a.length len = (); 
		BOOL = Sub to true; // if the new node 
		for (i = 0; I <len; I ++) 
			IF (isdigit (a [I])) { 
				IF (Trie [P] .num) return to true; /// reached the other end of the word, in fact, the template is determined mainly with respect to a plurality of here
				IDX = T (A [I]); 
		IF (OK)! cout <<"YES"<<endl;
				if(!trie[p].next[t]){
					sub = false; /// If the new node does not fully illustrate the tree traversal string prefix 
					P = Trie [P] .next [T] = size ++; 
					Trie [P] .num = 0; 
				} 
				the else Trie P = [P] .next [T]; 
			} 
		Trie [P] = .num ID; 
		return Sub; 
	} 
} Solver; 
int main () { 
	ios_base :: sync_with_stdio (to false); 
	int T, I; 
	String NUM; 
	CIN >> T; 
	the while (T -) { 
		solver.set (); // initialize 
		CIN n->>; 
		OK to false =; 
		for (I =. 1; I <= n-; I ++) { 
			CIN NUM >> ; 
			IF (! && solver.insert OK (NUM, I)) {// prefix appears 
				COUT << "NO" << endl; 
				OK = to true; 
			} 
		} 
	} 
}

 

P2292 [HNOI2004] L Language

This question is actually relative to the template out of a step, that is, each time you want to query string is not found in the future, then this string is not the place to start to re-iterate Find

#include <bits / STDC ++ H.> 
the using namespace STD; 
Long Long n-, m, SUM; 
String A; 
int Mark [1000005]; 
struct Node 
{ 
    int Son [26 is]; 
    int Mark; 
} Trie [1000005]; 
void the Add (string s) // achievements 
{ 
    Long Long POS = 0; 
    for (Long Long I = 0; I <= s.size () -. 1; I ++) 
    { 
        int now = S [I] - 'A'; 
        IF ( Trie [POS] .son [now] == 0) Trie [POS] .son [now] ++ = SUM; 
        POS = Trie [POS] .son [now]; 
    } 
    Trie [POS] =. 1 .mark; / / word end flag 
} 
void find (string S) 
{ 
    int ANS, POS = 0; 
    Memset (mark, 0, the sizeof (mark)); // initialize each must find a string!
    for (int j = 0; j <= s.size () - 1; j ++) // start and again! Otherwise, continue all the way to the following cycles passed directly qwq 
        { 
            int now = S [J] - 'A'; 
            POS = Trie [POS] .son [now]; 
            IF (POS == 0) BREAK; 
            IF (Trie [POS] ==. 1 .mark) Mark [J] =. 1; 
        } 
    for (int I = 0, K; I <= s.size () -. 1; I ++) 
    { 
        ! IF (Mark [I]) Continue; the else ANS = +. 1 I; 
        POS = 0; 
        for (int I = J +. 1; J <= s.size () -. 1; J ++) 
        { 
            int now = S [J] - 'A'; 
            POS = Trie [POS]. Son [now]; 
            IF (POS == 0) BREAK; 
            IF (Trie [POS] == .mark. 1) Mark [J] =. 1; 
        } 
    } 
    the printf ( "% D \ n-", ANS); 
}
int main()
{
    cin>>n>>m;
    for(int i=1;i<=n;i++)
    {
        cin>>a;
        add(a);
    }
    for(int i=1;i<=m;i++)
    {
        cin>>a;
        find(a);//查找
    }
    return 0;
}

  

P2536 [AHOI2005] virus detection

 

Ideas:

T R & lt I E + Tree Search

I use the DFS d f S

First, for all the RNA fragments are built into the Trie T R & lt I E tree go, then the template matching string like that

If a match is the location of letters, then we continue down match

If it is ? ?, We have to skip Trie T r i a e tree to match

If it is * *, we can consider simply ignore this bit, you can also directly as this one ? ? Point of view, or in Trie T r i skip an e tree, but on the template matching string still current position, so that we can achieve Trie T R & lt I E ignores match the number of tree

Once a match a success, and if there is a state we reach this point nothing is necessary, so open a bitset b i t S E t be enough of memory

#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
#include<bitset>
#define re register
#define maxn 500005
int son[maxn][4],flag[maxn];
int n,m,cnt,L,ans;
char S[1001],T[1001];
std::bitset<1001> f[maxn];
inline int read()
{
    char c=getchar();
    int x=0;
    while(c<'0'||c>'9') c=getchar();
    while(c>='0'&&c<='9')
      x=(x<<3)+(x<<1)+c-48,c=getchar();
    return x;
}
inline int ch(char p)
{
    if(p=='A') return 0;
    if(p=='G') return 1;
    if(p=='T') return 2;
    if(p=='C') return 3;
} 
Inline void INS () 
{ 
    int len = strlen (S +. 1); 
    int now = 0; 
    for (Re int I =. 1; I <= len; I ++) 
    { 
        IF (Son [now] [CH (S [! I])]) Son [now] [CH (S [I])] = CNT ++; 
        now Son = [now] [CH (S [I])]; 
    } 
    In Flag [now] ++; 
} 
void DFS (now int, int T) 
{ 
    IF (T == L +. 1) successfully matched // 
    { 
        ANS In Flag = + [now]; 
        In Flag [now] = 0; 
        return; 
    } 
    IF (F [now] [T]) return ; 
    f [now] [t] = 1; // memory of, because? And * characters may become arbitrary, so the program will certainly be repeated, so that the memory of the program has also been excluded repeated dfs waste of time 
    if (T [t]> = 'A' && T [t] <= 'Z') 
    { 
        IF (! Son [now] [CH (T [T])]) return;
        DFS (Son [now] [CH (T [T])], T +. 1); 
    } // letters, then we continue down to match 
    the else 
    { 
        IF (T [T] == '?') 
        { 
            for (int I = Re 0; I <. 4; I ++) 
            IF (Son [now] [I]) DFS (Son [now] [I], T +. 1); // ignore on a Trie, while the template sequence matching position plus. 1 
        } 
        IF (T [T] == '*') 
        { 
            DFS (now, T +. 1); // ignore *, i.e. with the characters 0 to replace it 
            for (re int i = 0; i < . 4; I ++) 
            IF (Son [now] [I]) dfs (Son [now] [I], T +. 1), dfs (Son [now] [I], T); 
            // first directly dfs this is a view as $ $, dfs second can be achieved instead of a plurality of characters *? 
        } 
    } 
} 
int main () 
{ 
    Scanf ( "% S",. 1 + T); 
    L = strlen (T +. 1 ); 
    n-= Read ();
    for(re int i=1;i<=n;i++)
        scanf("%s",S+1),ins();
    dfs(0,1);
    printf("%d\n",n-ans);
    return 0;
}

  

 

Guess you like

Origin www.cnblogs.com/hgangang/p/12333970.html