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;
}
相关文章推荐
- C++实现Trie字典树
- 字典树的C++实现 Implement of trie tree
- Trie (prefix tree) 实现 (C++)
- c++实现socket通信测试
- 二叉树C++实现
- C++实现求解最大公约数和最小公倍数
- 数字图像处理,相位相关图像配准算法的C++实现
- C++模板实现二叉查找树(四 广度优先遍历)
- C++实现最长公共子序列LCS问题
- C++垃圾回收器的实现(附auto_ptr 与CComPtr区别)
- C++程序设计语言 特别版 第10章 Date类 完整实现
- 用C++实现《经典c程序100例》(未完待续)
- C++ 使用模板实现的一个List
- 包装模式之代理模式C++实现
- 基于C++与JS技术实现的网上挂号助手
- 【CCF201709-1打酱油】C++代码实现
- Bezier曲线原理及实现代码(c++)
- C++实现势能函数
- c++实现复数类
- C++ 用两个栈实现一个队列