您的位置:首页 > 其它

HDU-1075-What Are You Talking About

2012-12-05 18:25 477 查看
http://acm.hdu.edu.cn/showproblem.php?pid=1075

/*
字典树(trie tree)

它使在字符串集合中查找某个字符串的操作的复杂度降到最大只需O(n),其中n为字符串的长度。
trie是典型的将时间置换为空间的算法。

trie的原理是利用字符串集合中字符串的公共前缀来降低时间开销以达到提高效率的目的。

它具有以下性质:
1,根结点不包含任何字符信息;
2,如果字符的种数为n,则每个结点的出度为n(这样必然会导致浪费很多空间,这也是trie的缺点);
3,查找,插入复杂度为O(n),n为字符串长度。

题目描述:
Ignatius最近遇到一个难题,老师交给他很多单词(只有小写字母组成,不会有重复的单词出现),
现在老师要他统计出以某个字符串为前缀的单词数量(单词本身也是自己的前缀).
*/

/*
#include <iostream>
#include<string>
using namespace std;

struct trieTree
{
//指针域
struct trieTree *child[26];

string s;
//数据域
int n;		//以根结点到当前结点为前缀的单词数
int flag ;	//标记是否有这个单词。

};
struct trieTree* root;

void create(struct trieTree *newnode)  //初始化节点
{
newnode = (struct trieTree*)malloc(sizeof(struct trieTree));
//初始化指针域
for(int i=0; i<26; i++) //NULL表示不存在
{
newnode->child[i] = NULL;
}

//初始化数据域
newnode->n = 1 ;
newnode->flag = 0 ;
//	newnode->s = "";
}

void insert(string st, char *word)  //插入单词
{

struct trieTree* currNode = root;	//currNode指向根节点
int len = strlen(word);

for(int i=0; i<len; i++)				//从根节点开始往下插入
{
if(currNode->child[word[i]-'a'] != NULL) 	//如果已经存在该节点
{
currNode = currNode->child[word[i]-'a'];

//对单词每个字母的操作
currNode->n = currNode->n + 1;
}
else
{
struct trieTree* newNode=NULL;
create (newNode); 	//生成新的节点
currNode->child[word[i]-'a'] = newNode;
currNode = newNode;
}
}
//对最后一个字母操作 currNode
currNode->flag ++ ;
currNode->s = st;

}

string find(char *word)  			//查找前缀,返回前缀个数
{
struct trieTree* currNode= root;	 //currNode指向根节点
int len = strlen(word);
if(len == 0)  				//如果长度为0,直接返回0
{
return 0;
}

for(int i=0; i<len; i++)			//从根节点开始往下找
{
if(currNode->child[word[i]-'a'] != NULL)
{
currNode = currNode->child[word[i]-'a'];
}
else
{
return 0;
}
}

//返回所求的数据
return currNode->s;
}

*/

#include<iostream>
#include<string>
using namespace std;

const int sonNum = 26, base='a';

struct Trie
{
int num;
struct Trie *son[sonNum];
bool terminal;
string s;
};

Trie *NewTrie()
{
Trie *temp = new Trie;
temp->num=1;
temp->terminal=false;
for(int i=0; i<26; i++)
temp->son[i]=NULL;
return temp;
}

void Inster(string st, Trie *pnt, char *s, int len)
{
Trie *temp = pnt;
for(int i=0; i<len; i++)
{
if(temp->son[s[i]-base]==NULL)
temp->son[s[i]-base] = NewTrie();
else
temp->son[s[i]-base]->num++;
temp=temp->son[s[i]-base];
}
temp->terminal=true;
temp->s=st;
}

int Find(Trie *pnt, char *s, int len)
{
Trie *temp=pnt;
for(int i=0; i<len; i++)
{
if(temp->son[s[i]-base]!=NULL)
temp=temp->son[s[i]-base];
else
return 0;
}
if(temp->terminal)
{
cout<<temp->s;
return 1;
}
return 0;
}

int main()
{
char word[3010];
string str;
Trie *T;
T = NewTrie();

gets(word);
while(true)
{
cin>>str;
if(str == "END")
break;
scanf("%s", word);

Inster(str, T, word, strlen(word));
}
getchar();

gets(word);
char ss[20];
while(gets(word) && strcmp("END", word) != 0)
{
int j=0;
for(int i=0; i<strlen(word); i++)
{
if(word[i]>='a' && word[i]<='z')
ss[j++] = word[i];
else
{
if(j)
{
ss[j]='\0';
if(Find(T, ss, strlen(ss))==0)
cout<<ss;
}
j=0;
printf("%c", word[i]);
}
}
if(j)
{
ss[j]='\0';
if(Find(T, ss, strlen(ss))==0)
cout<<ss;
}
printf("\n");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: