您的位置:首页 > 其它

HDU 1247 trie 一个单词是否是两个单词的连接

2013-01-10 22:09 288 查看
#include <iostream>
using namespace std;

char list[50001][26];
const int kind = 26;
int cnt = 0;

struct Treenode
{
bool flag;
Treenode *next[kind];
Treenode()
{
flag = false;
for ( int i = 0; i < kind; ++i )
next[i] = NULL;
}
} node[100000];  //静态trie

void Insert ( Treenode *&root, char *word )
{
Treenode *location = root;
if ( location == NULL )
{
location = &node[cnt++];
root = location;
}

int id, i = 0;
while ( word[i] )
{
id = word[i] - 'a';
if ( location->next[id] == NULL )
location->next[id] = &node[cnt++];
location = location->next[id];
++i;
}
location->flag = true; /*注意标记单词的最后一个字母,说明在这之前的字母组成一个单词,以便查询时划分*/
}

bool check ( Treenode *root, char* word )
{
Treenode *location = root;
if ( location == NULL ) return false;

int id, i = 0, len = strlen(word);
while ( word[i] )
{
id = word[i] - 'a';
if ( location->next[id] == NULL )
return false;
if ( i == len-1 && location->next[id]->flag == true )
return true;/*查找到最后一个字符时,节点的标记应该是true,这样才是完全匹配的*/
location = location->next[id];
++i;
}
return false;
}

bool Search ( Treenode *root, char * word )
{
Treenode *location = root;
if ( location == NULL ) return false;

int id, i = 0, len = strlen(word);
while ( word[i] )
{
id = word[i] - 'a';
if ( location->next[id] == NULL )
return false;
if ( location->next[id]->flag == true )/*当检测到一个标记时说明单词的前半部分已经检测到,现在只需检测后面一部分是否能由另一个单词构成*/
{
if ( i + 1 < len && check(root,&word[i+1]) )
return true;
}
location = location->next[id];
++i;
}
return false;
}

int main()
{
int i = 0, j;
Treenode *root = NULL;
while ( scanf("%s", list[i]) != EOF )
{
Insert(root,list[i]);
++i;
}

for ( j = 0; j < i; ++j )  //将单词保存在list再搜索一遍
{
if ( Search(root,list[j]) )
printf("%s\n",list[j]);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐