poj 2001 trie

第一道trie

还需要写题来建立自己的代码习惯。

 1 #include <cstdio>
 2 #include <vector>
 3 #include <algorithm>
 4 #define maxn 20010
 5 using namespace std;
 6
 7 struct node {
 8     char v;
 9     int sz;
10     bool isword, mark;
11     node *son[26], *pre;
12 }pool[maxn], *tail=pool, *null=pool;
13
14 char temp[100];
15 struct Trie {
16     node *root;
17     vector<node*> stk;
18     node* newnode( node *p, char v ) {
19         node *nd = ++tail;
20         nd->sz = 0;
21         nd->v = v;
22         nd->isword = nd->mark = false;
23         nd->pre = p;
24         for( int i=0; i<26; i++ ) nd->son[i] = null;
25         return nd;
26     }
27     void insert( const char *str ) {
28         if( !root ) root=newnode(null,‘^‘);
29         node *nd=root;
30         while(1) {
31             if( *str ) {
32                 if( nd->son[*str-‘a‘]==null ) nd->son[*str-‘a‘]=newnode(nd,*str-‘a‘);
33                 nd->sz++;
34                 nd = nd->son[*str-‘a‘];
35                 str++;
36             } else {
37                 nd->isword = true;
38                 stk.push_back( nd );
39                 return;
40             }
41         }
42     }
43     void make_mark( node *nd ) {
44         if( nd->isword ) {
45             nd->mark = true;
46             for( int i=0; i<26; i++ )
47                 if( nd->son[i]!=null ) make_mark(nd->son[i]);
48         } else if( nd->sz==1 ) {
49             nd->mark = true;
50         } else {
51             for( int i=0; i<26; i++ )
52                 if( nd->son[i]!=null ) make_mark(nd->son[i]);
53         }
54     }
55     char *get( node *bt ) {
56         while( !bt->mark ) bt=bt->pre;
57         int i;
58         for( i=0; bt!=root; i++,bt=bt->pre )
59             temp[i] = bt->v+‘a‘;
60         temp[i] = 0;
61         reverse( temp, temp+i );
62         return temp;
63     }
64     void print( node *nd ) {
65         fprintf( stderr, "nd %d ch %c mark %d\n", nd-pool, nd->v+‘a‘, nd->mark );
66         for( int i=0; i<26; i++ )
67             if( nd->son[i]!=null ) print(nd->son[i]);
68     }
69 }T;
70
71 void pt( char *st ) {
72     fprintf( stderr, "%s\n", st );
73 }
74 char str[1010][30];
75 int main() {
76     int i;
77     for( i=0; ; i++ ) {
78         if( scanf( "%s", str[i] )!=1 ) {
79             i--;
80             break;
81         }
82         T.insert( str[i] );
83     }
84     for( int i=0; i<26; i++ )
85         if( T.root->son[i]!=null )
86             T.make_mark( T.root->son[i] );
87     for( int t=0; t<=i; t++ )
88         printf( "%s %s\n", str[t], T.get(T.stk[t]) );
89 }

时间: 2024-09-30 19:42:27

poj 2001 trie的相关文章

Poj 2001 (Trie 前缀树)

#include<iostream> #include<cstdio> #include<cstring> #include<string> #include<cmath> #include<algorithm> #include<cmath> #include<vector> #include<queue> #include<map> #define MAXN 400010 #defi

POJ 2001 Shortest Prefixes (Trie)

题目链接:POJ 2001 Description A prefix of a string is a substring starting at the beginning of the given string. The prefixes of "carbon" are: "c", "ca", "car", "carb", "carbo", and "carbon"

poj 1056 Trie树判断哈夫曼编码是否合法

理解了Trie树然后就能1A   其实估计这个题随便做做就能A掉,可能不需要高级数据. 先贴吉林大学的代码模板 /*==================================================*| Trie树(k叉) | INIT: init(); | 注: tree[i][tk]>0时表示单词存在, 当然也可赋予它更多含义; \*==================================================*/ const int tk = 26,

POJ 2503 Trie

链接: http://poj.org/problem?id=2503 题意: 给定一些字符串以及它在外星语言中的对应翻译,现在有若外星语言中的串,要把它们翻译成英语 题解: 这道题map,hash,trie都是可以做的 然而我用g++提交发现map和trie都超时了,换成c++就全都过了 map用了1141ms,trie只要485ms 代码: 31 vector<string> word; 32 int pi =1; 33 34 struct Node { 35 int next[26]; 3

poj 2945 trie树统计字符串出现次数

用记录附加信息的val数组记录次数即可. PS:trie树还有种动态写法,使用指针和动态分配内存代替了连续的ch数组,更加节省内存. Reference:http://blog.csdn.net/architect19/article/details/8966247 1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 using namespace std; 5 #define maxnode

POJ 1816 Trie

链接: http://poj.org/problem?id=1816 题意: 先给你n个字符串,这些字符串包含小写字母,‘?’和‘*’,其中 ‘?’可以表示任意一个字符,‘*’可以表示任意长度的任意字符,包括0个 然后m次询问,每次给你一个字符串,问你它和哪些字符串匹配 题解: 5月第一发AC真不容易啊(其实上个月就该A的 这道题思路很简单,就是先建一个字典树,然后在字典树上跑dfs就好了,但是有几个需要注意的地方 当然如果方法不一样,可能就不会遇到这么多恶心的问题 首先最坑的就是题目中给的字符

POJ 3630 Trie

链接: http://poj.org/problem?id=3630 题意: 给你n个字符串,判断有没有字符串是其他字符串的前缀 题解: 建一个字典树,在插入的过程中,如果没有新建一个结点,那这个字符串肯定是其他字符串的前缀, 如果新建结点的时候发现,有的字符串以这个字符结尾,那肯定有字符串是这个字符串的前缀 代码: 31 int pi = 1; 32 int fg; 33 34 struct Node { 35 int next[10]; 36 bool end; 37 }tree[MAXN]

poj 2503 Trie树

典型的Trie树, 算是复习一下字符串吧, 就是输入有点恶心,代码如下: #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn = 500000+100; struct Trie{ bool isword; int next[26]; char words[15]; Trie(){ memset(next, -1, sizeof(next

POJ 2001

#include<iostream> using namespace std; const int kind=26; struct trienode { trienode * next[kind]; int branch; trienode() { branch=0; for(int i=0;i<kind;i++) next[i]=NULL; } }; class trie { trienode * root; public: trie() { root=NULL; } void ins