您的位置:首页 > 编程语言 > C语言/C++

Trie的C++实现及HDU1251,hdu1671

2014-04-16 16:20 351 查看
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<cstdlib>
using namespace std;
template<int Size>
struct trie_node{

bool terminable; //表示节点为字符串的结尾
int node;       //子节点的个数
trie_node *child[Size]; //儿子节点
trie_node():terminable(false), node(0){
memset(child,0,sizeof(child)); //初始化节点
}

};
template<int Size,typename Index>
class trie{
public:
//定义类名
typedef trie_node<Size> node_type;
typedef trie_node<Size> *link_type;

//构造函数
trie(Index i=Index()):index(i){ }

//清空函数,用于析构
void clear(){
clear_node(root);
for(int i=0;i<Size;i++)
root.child[i]=0;
}
//插入
template<typename Iterator>
void insert(Iterator begin,Iterator end){
link_type cur= &root;//当前插入结点为根
while(begin!=end){
if(!cur->child[index[*begin]]){//没有插入过
cur->child[index[*begin]]=new node_type;
cur->node++; //插入后,父亲多了一个儿子
}
cur=cur->child[index[*begin]]; //向下走
begin++; //迭代器往前走!
}
cur->terminable=true;

}

//重载c风格插入
void insert(const char * str){
insert(str,str+strlen(str));
}

//查找
template <typename Iterator>
bool find(Iterator begin,Iterator end){
link_type cur=&root;
while(begin!=end){

if(!cur->child[index[*begin]]) //没有节点啊!!!
return false;
cur=cur->child[index[*begin]];

begin++;

}
return cur->terminable; //是否为字符串
}

//重载c风格
bool find(const char *str){

return find(str,str+strlen(str));
}

//删除字符串
template<typename Iterator>
bool earse (Iterator begin,Iterator end){
bool result;
earse_node(begin,end,root,result);
return result;

}

//c语言风格
bool erase(char *str){
return earse(str,str+strlen(str));

}

template<typename Functor>
void traverse(Functor &execute =Functor()){
visit_node(root,execute);

}
private:
//访问结点
template<typename Functor>
void visit_node(node_type cur,Functor &execute){
execute(cur);
for(int i=0;i<Size;i++){//dfs
if(cur.child[i]==0) continue;
visit_node(*cur.child[i],execute);

}
}

//清空
void clear_node(node_type cur){
for(int i=0;i<Size;i++){
if(cur.child[i]==0)continue; //不存在
clear_node(*cur.child[i]);
delete cur.childe[i];
cur.child[i]=0;
if(--cur.node==0) break; //没有节点了

}

}

//一边搜索一边删除
template<typename Iterator>
bool earse_node(Iterator begin ,Iterator end,node_type &cur,bool &result){
if(begin==end){
result=cur.terminable;
cur.terminalbe=false;
return cur.node==0;

}
//当孩子不存在,结果假,返回假
if(cur.child[index[*begin ]]==0) return !(result=false);
else if(earse_node(begin+1,end,*(cur.child[index[*begin]]),result)){
delete cur.child[index[*begin]];
cur.child[index[*begin]]=0;
if(--cur.node==0&&cur.terminable==false ) return true;

}
return false;

}
//根
node_type root;
//字符转索引,类似hash
Index index;

};

class IndexClass{
public:
int operator[](const char key){
return key%26; //一个映射

}

};

int main(){
trie<26,IndexClass> t;
t.insert("tree");
t.insert("tea");
t.insert("act");
t.insert("adv");
t.insert("ate");
if(t.find("tree")){
cout<<"find!";
}
char  str[50];
while(scanf("%s",str)!=EOF){
if(t.find(str)==1){
cout<<"find"<<endl;
}

}
return 0;

}

大部分参考http://blog.csdn.net/luxiaoxun/article/details/7937589

后来用1251裸题测试了一下。

Ac果断高兴啊!

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<cstdlib>
using namespace std;
template<int Size>
struct trie_node{

bool terminable; //表示节点为字符串的结尾
int node;       //子节点的个数
trie_node *child[Size]; //儿子节点
trie_node():terminable(false), node(0){
memset(child,0,sizeof(child)); //初始化节点
}

};
template<int Size,typename Index>
class trie{
public:
//定义类名
typedef trie_node<Size> node_type;
typedef trie_node<Size> *link_type;

//构造函数
trie(Index i=Index()):index(i){ }

//清空函数,用于析构
void clear(){
clear_node(root);
for(int i=0;i<Size;i++)
root.child[i]=0;
}
//插入
template<typename Iterator>
void insert(Iterator begin,Iterator end){
link_type cur= &root;//当前插入结点为根
while(begin!=end){
if(cur->child[index[*begin]]){//插入过
cur=cur->child[index[*begin]];
++(cur->node);

}else{
cur->child[index[*begin]]=new node_type;
++(cur->child[index[*begin]]->node);
cur=cur->child[index[*begin]];

}

begin++; //迭代器往前走!
}
cur->terminable=true;

}

//重载c风格插入
void insert(const char * str){
insert(str,str+strlen(str));
}

//查找
template <typename Iterator>
bool find(Iterator begin,Iterator end){
link_type cur=&root;
while(begin!=end){

if(!cur->child[index[*begin]]) //没有节点啊!!!
return false;
cur=cur->child[index[*begin]];

begin++;

}
return cur->terminable; //是否为字符串
}
template <typename Iterator>
int findNum(Iterator begin,Iterator end){
link_type cur=&root;
while(begin!=end){

if(!cur->child[index[*begin]]) //没有节点啊!!!
return 0;
cur=cur->child[index[*begin]];

begin++;

}

return cur->node; //是否为字符串
}
//重载c风格
int findNum(const char *str){

return findNum(str,str+strlen(str));
}

//重载c风格
bool find(const char *str){

return find(str,str+strlen(str));
}

//删除字符串
template<typename Iterator>
bool earse (Iterator begin,Iterator end){
bool result;
earse_node(begin,end,root,result);
return result;

}

//c语言风格
bool erase(char *str){
return earse(str,str+strlen(str));

}

template<typename Functor>
void traverse(Functor &execute =Functor()){
visit_node(root,execute);

}
private:
//访问结点
template<typename Functor>
void visit_node(node_type cur,Functor &execute){
execute(cur);
for(int i=0;i<Size;i++){//dfs
if(cur.child[i]==0) continue;
visit_node(*cur.child[i],execute);

}
}

//清空
void clear_node(node_type cur){
for(int i=0;i<Size;i++){
if(cur.child[i]==0)continue; //不存在
clear_node(*cur.child[i]);
delete cur.childe[i];
cur.child[i]=0;
if(--cur.node==0) break; //没有节点了

}

}

//一边搜索一边删除
template<typename Iterator>
bool earse_node(Iterator begin ,Iterator end,node_type &cur,bool &result){
if(begin==end){
result=cur.terminable;
cur.terminalbe=false;
return cur.node==0;

}
//当孩子不存在,结果假,返回假
if(cur.child[index[*begin ]]==0) return !(result=false);
else if(earse_node(begin+1,end,*(cur.child[index[*begin]]),result)){
delete cur.child[index[*begin]];
cur.child[index[*begin]]=0;
if(--cur.node==0&&cur.terminable==false ) return true;

}
return false;

}
//根
node_type root;
//字符转索引,类似hash
Index index;

};

class IndexClass{
public:
int operator[](const char key){
return key%26; //一个映射

}

};

int main(){
trie<26,IndexClass> t;
char s[11];
//freopen("in.txt","r",stdin);

while(gets(s) && s[0])
{
t.insert( s);
}

while(gets(s))
{
printf("%d\n", t.findNum(s));
}

return 0;

}


HDU1671

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<cstdlib>
#include<vector>
using namespace std;
#define MAXN 10
template<int Size>
struct trie_node
{

bool terminable; //表示节点为字符串的结尾
int node; //子节点的个数
trie_node *child[Size]; //儿子节点
trie_node():terminable(false), node(0)
{
memset(child,0,sizeof(child)); //初始化节点
}

};
template<int Size,typename Index>
class trie
{
public:
//定义类名
typedef trie_node<Size> node_type;
typedef trie_node<Size> *link_type;

//构造函数
trie(Index i=Index()):index(i) { }

//清空函数,用于析构
void clear()
{
clear_node(root);
for(int i=0; i<Size; i++)
root.child[i]=0;
}
//插入
template<typename Iterator>
void insert(Iterator begin,Iterator end)
{
link_type cur= &root;//当前插入结点为根
while(begin!=end)
{
if(cur->child[index[*begin]]) //插入过
{
cur=cur->child[index[*begin]];
cur->node++;

}
else
{
cur->child[index[*begin]]=new node_type;
cur->child[index[*begin]]->node++;
cur=cur->child[index[*begin]];

}
begin++; //迭代器往前走!
}
cur->terminable=true;

}

//重载c风格插入
void insert(const char * str)
{
insert(str,str+strlen(str));
}

//插入与判断
template<typename Iterator>
bool insert2(Iterator begin,Iterator end)
{
link_type cur= &root;//当前插入结点为根

bool flag=0;
while(begin!=end)
{
if(cur->child[index[*begin]]) //插入过
{
if(cur->child[index[*begin]]->terminable==true){

flag=1;
}
cur=cur->child[index[*begin]];
cur->node++;

}
else
{
cur->child[index[*begin]]=new node_type;
cur->child[index[*begin]]->node++;
cur=cur->child[index[*begin]];

}
begin++; //迭代器往前走!
}
cur->terminable=true;
return flag;

}

//重载c风格插入
bool insert2(const char * str)
{
return insert2(str,str+strlen(str));
}

//查找
template <typename Iterator>
bool find(Iterator begin,Iterator end)
{
link_type cur=&root;
while(begin!=end)
{

if(!cur->child[index[*begin]]) //没有节点啊!!!
return false;
cur=cur->child[index[*begin]];

begin++;

}
return cur->terminable; //是否为字符串
}
//重载c风格
bool find(const char *str)
{

return find(str,str+strlen(str));
}

//查找节点数目
template <typename Iterator>
int findNum(Iterator begin,Iterator end)
{
link_type cur=&root;
while(begin!=end)
{

if(!cur->child[index[*begin]]) //没有节点啊!!!
return 0;
cur=cur->child[index[*begin]];

begin++;

}

return cur->node; //是否为字符串
}
//重载c风格
int findNum(const char *str)
{

return findNum(str,str+strlen(str));
}

//查找前缀
template <typename Iterator>
bool findPre(Iterator begin,Iterator end)
{
link_type cur=&root;
while(begin!=end)
{

if(!cur->child[index[*begin]]) //没有节点啊!!!
return false;

if(cur->terminable) break;
cur=cur->child[index[*begin]];

begin++;

}
return begin!=end; //是否为字符串
}

bool findPre(const char *str){
return findPre(str,str+strlen(str));

}

//删除字符串
template<typename Iterator>
bool earse (Iterator begin,Iterator end)
{
bool result;
earse_node(begin,end,root,result);
return result;

}

//c语言风格
bool erase(char *str)
{
return earse(str,str+strlen(str));

}

template<typename Functor>
void traverse(Functor &execute =Functor())
{
visit_node(root,execute);

}
private:
//访问结点
template<typename Functor>
void visit_node(node_type cur,Functor &execute)
{
execute(cur);
for(int i=0; i<Size; i++) //dfs
{
if(cur.child[i]==0) continue;
visit_node(*cur.child[i],execute);

}
}

//清空
void clear_node(node_type cur)
{
for(int i=0; i<Size; i++)
{
if(cur.child[i]==0)continue; //不存在
clear_node(*cur.child[i]);
delete cur.child[i];
cur.child[i]=0;
if(--cur.node==0) break; //没有节点了

}

}

//一边搜索一边删除
template<typename Iterator>
bool earse_node(Iterator begin ,Iterator end,node_type &cur,bool &result)
{
if(begin==end)
{
result=cur.terminable;
cur.terminalbe=false;
return cur.node==0;

}
//当孩子不存在,结果假,返回假
if(cur.child[index[*begin ]]==0) return !(result=false);
else if(earse_node(begin+1,end,*(cur.child[index[*begin]]),result))
{
delete cur.child[index[*begin]];
cur.child[index[*begin]]=0;
if(--cur.node==0&&cur.terminable==false ) return true;

}
return false;

}
//根
node_type root;

//字符转索引,类似hash
Index index;

};

class IndexClass
{
public:
int operator[](const char key)
{
return key%MAXN; //一个映射

}

};

char s[10000][11];
int main()
{
trie<MAXN,IndexClass> t;

int T,n,i;
// freopen("in.txt","r",stdin);
scanf("%d",&T);

while(T--)
{
scanf("%d",&n);

t.clear();
for(i=0;i<n;i++){

scanf("%s",s[i]);

t.insert(s[i]);

}
for(i=0;i<n;i++){

if(t.findPre(s[i])){

puts("NO");
break;
}
}
if(i==n) puts("YES");

}

return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: