poj1056 (Trie入门)寻找字符串前缀

时间:2023-03-09 04:29:19
poj1056     (Trie入门)寻找字符串前缀

题意:给你一堆字符串,问是否满足对于任意两个字符串a、b,a不是b的前缀

字典树==前缀树==Trie树

trie入门题,只用到了insert和query操作

 #include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
#define maxnode 1000
#define sigma_size 30 //struct Trie
//{
int ch[maxnode][sigma_size]; //ch[i][j]:记录结点i的那个编号为j的子节点
int val[maxnode]; //val[i]:i节点的附加信息,这里我们用来记录是否到一个单词的结束
//(即在trie树上root->i一路下来是否是一个完整的单词)
int sz;
void Trie()
{
sz=;
memset(ch[],,sizeof(ch[]));
}
int idx(char c) //idx(c)即字符c的编号。
{
return c-''; //此处第一个字符是0所以return c-'0'
}
void Insert(string s,int v)
{
int u=,n=s.length();
for (int i=;i<n;i++)
{
int c=idx(s[i]);
if (!ch[u][c])
{
memset(ch[sz],,sizeof(ch[sz]));
val[sz]=;
ch[u][c]=sz++;
}
u=ch[u][c];
}
val[u]=v;
}
bool query(string s) //true:s is a prefix
{
int u=,c;
for (int i=;i<s.length();i++)
{
c=s[i]-'';
if (!ch[u][c]) return false; u=ch[u][c];
if (val[u]==) return true; //若此时s还没走完但trie树上已经走到结尾了,即树上单词是s的前缀
}
return true;
}
//}; bool ok;
string str; int main()
{
//freopen("in.txt","r",stdin); ok=true;
Trie();
int num=;
while (cin>>str)
{
if (str=="")
{
num++;
if (ok)
printf("Set %d is immediately decodable\n",num);
else
printf("Set %d is not immediately decodable\n",num);
ok=true;
Trie();
}
else
{
if (query(str))
ok=false;
Insert(str,);
}
}
}

扩展:

1.用trie实现字符串排序?

直接对trie树前序遍历一遍即可

http://www.cnblogs.com/shuaiwhu/archive/2012/05/05/2484676.html

2.trie还有删除操作,不过实现比较麻烦。先mark一个

http://www.cnblogs.com/dolphin0520/archive/2011/10/11/2207886.html

3.trie在中文分词中的应用

http://blog.csdn.net/wzb56_earl/article/details/7902669