hihocoder #1014 题目地址:http://hihocoder.com/problemset/problem/1014

hihocoder #1036 题目地址: http://hihocoder.com/problemset/problem/1036

trie图其实就是trie树+KMP

#1014trie树

#include<stdio.h>
#include <algorithm>
#include <cstring>
#include <string.h>
#include <iostream>
#include <list>
#include <map>
#include <set>
#include <stack>
#include <string>
#include <utility>
#include <vector>
#include <cstdio>
#include <cmath> using namespace std; typedef struct Trie_node
{
int count; // 统计单词前缀出现的次数
struct Trie_node* next[]; // 指向各个子树的指针
bool exist; // 标记该结点处是否构成单词
}TrieNode , *Trie; Trie createTrieNode()
{
TrieNode* node = (TrieNode *)malloc(sizeof(TrieNode));
node->count = ;
node->exist = false;
memset(node->next , , sizeof(node->next)); // 初始化为空指针
return node;
} void Trie_insert(Trie root, char* word)
{
Trie node = root;
char *p = word;
int id;
while( *p )
{
id = *p - 'a';
if(node->next[id] == NULL)
{
node->next[id] = createTrieNode();
}
node = node->next[id];
++p;
node->count += ; // 包括统计每个单词出现的次数
}
node->exist = true; // 可以构成一个单词
} int Trie_search(Trie root, char* word)
{
Trie node = root;
char *p = word;
int id;
while( *p )
{
id = *p - 'a';
node = node->next[id];
++p;
if(node == NULL)
return ;
}
return node->count;
} int main()
{
Trie root = createTrieNode(); // 字典树的根节点
char str[] ;
bool flag = false;
int n ,m ;
scanf ("%d", &n);
for( int i = ; i < n ; i++)
{
scanf ("%s", str);
Trie_insert(root , str);
}
scanf ("%d", &m);
for( int i = ; i < m ; i++)
{
scanf ("%s", str);
printf("%d\n",Trie_search(root , str));
}
return ;
}

#1036trie图

其实就是trie树+KMP

数据结构与trie树一样,加了一个prev指针,作用类似于KMP的失配函数next[]

Trie_insert函数不变

添加一个构造prev的函数Trie_build()。

prev指针的作用:在匹配失败时跳转到具有公共前缀的字符继续匹配,类似于KMP的失配函数next[]。

利用bfs构造prev指针。

指针prev指向与字符p相同的结点,如果没有与p前缀相同的节点,则指向root

根节点的前缀是根节点

最后字符匹配的Trie_search()函数类似于KMP的过程,在当前字符匹配失败时,利用prev指针跳转到具有最长公共前后缀的字符继续匹配。

#include<stdio.h>
#include <algorithm>
#include <cstring>
#include <string.h>
#include <iostream>
#include <list>
#include <map>
#include <set>
#include <stack>
#include <string>
#include <utility>
#include <queue>
#include <vector>
#include <cstdio>
#include <cmath> using namespace std; typedef struct Trie_node
{
int count; // 统计单词前缀出现的次数
struct Trie_node* next[];
bool exist; // 标记该结点处是否构成单词
struct Trie_node* prev; //前缀节点
}TrieNode , *Trie; Trie createTrieNode()
{
TrieNode* node = (TrieNode *)malloc(sizeof(TrieNode));
node->prev=NULL;
node->count = ;
node->exist = false;
memset(node->next , , sizeof(node->next));
return node;
} void Trie_insert(Trie root, char* word)
{
Trie node = root;
char *p = word;
int id;
while( *p )
{
id = *p - 'a';
if(node->next[id] == NULL)
{
node->next[id] = createTrieNode();
}
node = node->next[id];
++p;
node->count += ; // 统计每个单词出现的次数
}
node->exist = true; // 单词结束的地方标记
} void Trie_build(Trie root) //Trie树和Tie图的区别就在于此,类似于KMP构造失配函数的一个过程
{
queue<Trie> Q; //利用bfs构造prev指针,队列实现BFS
Trie node=root;
for(int i=;i<;i++)//根节点的子节点的rev都是根节点,根节点的prev也是根节点
{
if(node->next[i]!=NULL)
{
node->next[i]->prev=root;
Q.push(node->next[i]);
}
}
while(!Q.empty())
{
node=Q.front();
Q.pop();
for(int i=; i<; i++)
{
Trie p=node->next[i];
if(p!=NULL&&p->exist==false) //若此处能构成单词则不用处理prev
{
Trie prev=node->prev; //上一个结点的前缀节点
while(prev)
{
if(prev->next[i]!=NULL)
{
p->prev=prev->next[i]; //prev指向与字符p相同的结点
if(p->prev->exist==true)
p->exist=true;
break;
}
else
prev=prev->prev;
} if(p->prev==NULL)//如果没有与p前缀相同的节点,则指向root
p->prev=root;
Q.push(p);
}
}
}
} bool Trie_search(Trie root, char* word)
{
Trie node = root;
char *p = word;
int id;
while( *p )
{
id = *p - 'a';
while(true)
{
if(node->next[id]!=NULL) //匹配成功
{
node = node->next[id];
if(node->exist)
return true;
break;
}
else node=node->prev; //类似KMP的失配过程,在当前字符匹配失败时,跳转到具有最长公共前后缀的字符继续匹配
if(node==root||node==NULL){
node=root;
break;
}
}
p++;
}
return false;
} char str[] ;
int main()
{
Trie root = createTrieNode(); // 初始化字典树的根节点
bool flag = false;
int n ;
scanf ("%d", &n);
for( int i = ; i < n ; i++)
{
scanf ("%s", str);
Trie_insert(root , str);
}
Trie_build(root);
scanf ("%s", str);
if(Trie_search(root , str)) printf("YES\n");
else printf("NO\n");
return ;
}

hiho一下 第二周&第四周:从Trie树到Trie图的更多相关文章

  1. 笔试算法题(39):Trie树(Trie Tree or Prefix Tree)

    议题:TRIE树 (Trie Tree or Prefix Tree): 分析: 又称字典树或者前缀树,一种用于快速检索的多叉树结构:英文字母的Trie树为26叉树,数字的Trie树为10叉树:All ...

  2. hiho一下 第二周 trie树

    Trie树 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi和小Ho是一对好朋友,出生在信息化社会的他们对编程产生了莫大的兴趣,他们约定好互相帮助,在编程的学习道路 ...

  3. 编程之美--2. Trie树 (Trie图)

    #1014 : Trie树 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi和小Ho是一对好朋友,出生在信息化社会的他们对编程产生了莫大的兴趣,他们约定好互相帮助, ...

  4. 双数组Trie树 (Double-array Trie) 及其应用

    双数组Trie树(Double-array Trie, DAT)是由三个日本人提出的一种Trie树的高效实现 [1],兼顾了查询效率与空间存储.Ansj便是用DAT(虽然作者宣称是三数组Trie树,但 ...

  5. hihoCoder 1014 Trie树 (Trie)

    #1014 : Trie树 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描写叙述 小Hi和小Ho是一对好朋友.出生在信息化社会的他们对编程产生了莫大的兴趣,他们约定好互相帮 ...

  6. hiho一下第二周 Trie树

    题目链接:http://hihocoder.com/problemset/problem/1014 #include <iostream> #include <cstdio> ...

  7. hihoCoder hiho一下 第二周 #1014 : Trie树(Trie树基本应用)

    思路: 完全看题目中的介绍就行了.还有里面的input写道:不保证是英文单词,也有可能是火星文单词哦.比赛结束后的提交是不用考虑26个字母之外的,都会AC,如果考虑128种可能的话,爆了内存.步骤就是 ...

  8. 【hiho一下第二周 】Trie树

    [题目链接]:http://hihocoder.com/problemset/problem/1014 [题意] [题解] 在字典树的域里面加一个信息cnt; 表示这个节点下面,记录有多少个单词; 在 ...

  9. hihocoder_1014: Trie树(Trie树模板题)

    题目链接 #include<bits/stdc++.h> using namespace std; ; struct T { int num; T* next[]; T() { num=; ...

随机推荐

  1. Linux用ps命令查找进程PID再用kill命令终止进程的方法

    使用linux操作系统,难免遇到一些软件"卡壳"的问题,这时就需要使用linux下强大的kill命令来结束相关进程.这在linux系统下是极其容易的事情,你只需要kill xxx即 ...

  2. django book用户认证学习

    用户与Authentication 通过session,我们可以在多次浏览器请求中保持数据, 接下来的部分就是用session来处理用户登录了. 当然,不能仅凭用户的一面之词,我们就相信,所以我们需要 ...

  3. README.md文档

    大标题 =================================== 大标题一般显示工程名,类似html的\<h1\> 你只要在标题下面跟上=====即可 中标题 ------- ...

  4. Java源码阅读Stack

    Stack(栈)实现了一个后进先出(LIFO)的数据结构.该类继承了Vector类,是通过调用父类Vector的方法实现基本操作的. Stack共有以下五个操作: put:将元素压入栈顶. pop:弹 ...

  5. asp.net限制用户登录错误次数

    很经常在登录一个网站的时候看到,如果你登录的时候输入的账号密码错误超过三次就被锁定,然后等一段时间才能继续登录,最最经常使用的就是银行系统啦~~ 该功能处理流程如下: string uid = Req ...

  6. idea 热部署

  7. jsp中URL传递中文參数的处理

    在页面的url中使用encodeURI(encodeURI(中文)).对中文进行编码.并在server的java程序中使用URLDecoder.decode(中文, "UTF-8" ...

  8. Angular 学习笔记——run

    <!DOCTYPE html> <html lang="en" ng-app="myApp"> <head> <met ...

  9. PS 如何制作Vista的毛玻璃效果

    1 对一个图像的任意一部分新建一个选区   2 对选中区域进行高斯模糊,大小为5像素   3 再次新建一个图层,填充为深蓝色(#E9E7E3),填充为10%-15%.高斯模糊0.5像素.   4 再对 ...

  10. Python学习笔记(一)类和继承的使用

    一年前就打算学Python了,折腾来折腾去也一直没有用熟练,主要是类那一块不熟,昨天用Python写了几个网络编程的示例,感觉一下子迈进了很多.这几天把学习Python的笔记整理一下,内容尽量简洁. ...