#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; }

Trie的C++实现及HDU1251,hdu1671的更多相关文章

  1. 蒟蒻的trie树专题

    POJ 3630 Phone List: 模板 ///meek #include<bits/stdc++.h> using namespace std; using namespace s ...

  2. 3道入门字典树例题,以及模板【HDU1251/HDU1305/HDU1671】

    HDU1251:http://acm.hdu.edu.cn/showproblem.php?pid=1251 题目大意:求得以该字符串为前缀的数目,注意输入格式就行了. #include<std ...

  3. Trie 字典树,hdu1251

    参考博客:https://www.cnblogs.com/TheRoadToTheGold/p/6290732.html 字典树就是单词树,顺着一条路径到达终止结点就形成一个单词,该单词的前缀包含在这 ...

  4. hdu----(1671)Phone List(Trie带标签)

    Phone List Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  5. HDU1251 统计难题 Trie树

    题目很水,但毕竟是自己第一道的Trie,所以还是发一下吧.Trie的更多的应用慢慢学,AC自动机什么的也慢慢学.... #include<iostream> #include<cst ...

  6. HDU1671 - Phone List(Trie树)

    题目大意 给定一些电话号码,判断是否有电话号码是其他电话号码的前缀 题解 裸Trie树嘛~~~~只需要一个插入过程即可,假设X是Y的前缀,在插入的过程中有两种情况,X在Y之前插入,那么在插入Y的时候经 ...

  7. HDU1251 统计难题(Trie)

    统计难题 Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131070/65535 K (Java/Others) Total Subm ...

  8. hdu1251(Trie树)

    传送门:统计难题 分析:Trie树入门题,随便写写练下手感,统计每个节点被多少单词经过就可以了. #include <iostream> #include <cstdio> # ...

  9. [hdu1251]统计难题(trie模板题)

    题意:返回字典中所有以测试串为前缀的字符串总数. 解题关键:trie模板题,由AC自动机的板子稍加改造而来. #include<cstdio> #include<cstring> ...

随机推荐

  1. MapReduce的流程

    1. Inputformat会从job的INPUT_DIR目录下读入待处理的文件,检查输入的有效性并将文件切分成InputSplit列表.Job实例可以通过setInputFormatClass(Cl ...

  2. 编写一个Shape类,具有属性:周长和面积; 定义其子类三角形和矩形,分别具有求周长的方法。 定义主类E,在其main方法中创建三角形和矩形类的对象, 并赋给Shape类的对象a、b,使用对象a、b来测试其特性。

    package shape; public class Shape { //定义成员变量 private double zhouchang; private double mianji; public ...

  3. java 对视频和图片进行加密解密

    import java.io.File;import java.io.FileInputStream;import java.io.FileNotFoundException;import java. ...

  4. HTML5----CSS显示半个字符

    CSS显示半个字符的基本思路: 就是一个字写两遍,分别显示一半.这里就须要用到CSS伪元素:before和:after,记住这个"伪元素"的"伪"字,表明它本来 ...

  5. ArrowDrawable

    https://github.com/wly2014/ArrowDrawable https://github.com/ChrisRenke/DrawerArrowDrawable

  6. [React Native] Using the Image component and reusable styles

    Let's take a look at the basics of using React Native's Image component, as well as adding some reus ...

  7. JavaScript(20)jQuery HTML 加入和删除元素

    jQuery - 加入元素 通过 jQuery,能够非常easy地加入新元素/内容. 加入新的 HTML 内容的四个 jQuery 方法: append() - 在被选元素的结尾插入内容 prepen ...

  8. 内核日志及printk结构浅析

      作者:tekkamanninja 鸣谢:感谢ChinaUnix技术社区的tekkamanninja提供稿件 ,如需转载,请注明出处. 这段时间复习了一下内核调试系统,注意看了一下printk的实现 ...

  9. linux文件 编辑常用 inux手把手vi ---针对文件操作

    命令语法 说明 使用频率(1:常用;2一般:3:偶尔) 1.VI编辑器的启动与退出 VI编辑器的启动与退出 vi  file1 新建一个文本文件名为file1 :q 退出,如果对缓存去进行过修改,则提 ...

  10. 在aws ec2上使用root用户登录

    aws ec2默认是使用ec2-user账号登陆的,对很多文件夹是没有权限的.如何使用root账号执行命令就是一个问题了.解决办法如下: 1.根据官网提供的方法登录连接到EC2服务器(官网推荐wind ...