以后有好多次看到这地方就过去了,
未亲自实践过。
不过今晚看了一下,感觉trie的思想还算是比较基础的。
感觉这一个链接讲的不错:http://www.cnblogs.com/BeyondAnyTime/archive/2012/07/16/2592838.html
顺便水了几道题。
具体列表可见:http://vjudge.net/contest/view.action?cid=47036#overview
A:水题啦。 稍微理解下trie就能写出来了。
附个自己写的代码,还是用LRJ书上的非指针代码比较好。 当然我的注释里也有指针版的,指针版的容易爆内存。
ps:这个MAX_NODE的数量还不是太会确定。
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #include <vector> #include <cmath> #include <queue> #include <stack> #include <map> #include <set> using namespace std; #define clr(x) memset(x,0,sizeof(x)) #define fp1 freopen("in.txt","r",stdin) #define fp2 freopen("out.txt","w",stdout) #define pb push_back #define INF 0x3c3c3c3c typedef long long LL; const int MAX = 500000; //int up; //struct Node{ // int c[26]; //26 仅限26个小写字母(或大写) // bool isword; // Node(){ // up++; // isword = false; // memset(c, 0, sizeof(c)); // } //}trie[MAX]; // //void trieBuild(){ // up = 0; // trie[0] = Node(); //} // //void trieAdd(char *s){ // int i, now = 0; // for(i = 0;s[i];++i){ // int p = s[i]-'a'; // if(trie[now].c[p]==0) { // trie[now].c[p] = up; // trie[up] = Node(); // } // now = trie[now].c[p]; // } // trie[now].isword = true; //} // //bool trieFind(char *s){ // int i, now = 0; // for(i = 0;s[i];++i){ // int p = s[i]-'a'; // if(trie[now].c[p] == 0) return false; // now = trie[now].c[p]; // } // return trie[now].isword; //} //struct node { // int num ; // node *next[26]; //} ; //node * root; // //void trieBuild(){ // int i,j; // root = new node; // root->num = 0; // for(int i=0;i<=25;i++){ // root ->next[i] = NULL; // } //} // //void trieInsert(char ss[]){ // node *p = root,*t; // for(int i=0;ss[i];i++){ // int id = ss[i]-'a'; // if(!p->next[id]){ // t = new node; // t->num = 0 ; // for(int j=0;j<26;j++) // t->next[j] = NULL; // p->next[id] = t; // } // p=p->next[id]; // p->num ++ ; // } // // //} // //int trieSearch (char ss[]){ // node *p= root; // for(int i=0 ;ss[i];i++){ // int t = ss[i] - 'a'; // if(p->next[t]){ // p = p->next[t]; // }else { // return 0; // } // } // return p->num ; //} struct Trie{ int ch[MAX][26]; int val[MAX]; int sz; //结点总数 Trie() { sz = 1; memset(ch[0],0,sizeof(ch[0]));} //初始只有一个根结点 int idx(char c) { return c-'a';} //v必须非0,因为0代表“本结点不是单词结点” void insert(char *s, int v){ int u = 0, n = strlen(s); for(int i = 0;i < n;i++){ int c = idx(s[i]); if(!ch[u][c]) { memset(ch[sz], 0, sizeof(ch[sz])); val[sz] = 0; ch[u][c] = sz++; } u = ch[u][c]; val[u] ++; } } int query(char *s){ int u = 0, n = strlen(s); for(int i = 0;i < n;i++){ int c = idx(s[i]); if(!ch[u][c]) return 0; u = ch[u][c]; } return val[u]; } }test; char str[100]; int main() { //fp1; while(gets(str)){ if(!strcmp(str,"")) break; else test.insert(str, 0); } while(gets(str)){ printf("%d\n", test.query(str)); } return 0; }
trie/字典树几题
时间: 2024-10-18 23:44:29