Problem - 1277

  无聊做水题的时候发现的一道题目。这道题第一反应可以用自动机来解决。当然,条件是各种限制,从而导致可以用直接映射标记的方法来搜索。具体的做法就像RK算法一样,将字符串hash成一个数,这里每一个关键字前四位都是不同的,这样就有利于hash搜索了。当前四位匹配的时候,就可以搜索整个串是否完全匹配。这整个的复杂度大概是O(n*m),n是全文测长度,m是关键字的长度。

自动机代码:

 #include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <queue>
#include <set> using namespace std; const int kind = ;
struct Node {
Node *next[kind];
Node *fail;
string label;
Node() {
memset(next, , sizeof(next));
fail = NULL;
label = "";
}
Node(char *tmp) {
memset(next, , sizeof(next));
fail = NULL;
label = tmp;
}
} ; struct Trie {
Node *Root;
Trie() { Root = new Node();} void insert(char *s, char *label) {
Node *p = Root;
while (*s) {
int idx = *s - '';
if (!p->next[idx]) {
p->next[idx] = new Node();
p->next[idx]->fail = p;
}
p = p->next[idx];
s++;
}
p->label = label;
}
void build() {
queue<Node *> Q;
while (!Q.empty()) Q.pop();
Q.push(Root);
Root->fail = NULL;
Node *cur, *p;
while (!Q.empty()) {
cur = Q.front();
Q.pop();
for (int i = ; i < kind; i++) {
// cout << cur->next[i] << ' ';
if (cur->next[i]) {
// cout << i << ' ';
Q.push(cur->next[i]);
p = cur->fail;
while (p) {
if (p->next[i]) {
cur->next[i]->fail = p->next[i];
break;
}
p = p->fail;
}
if (!p) cur->next[i]->fail = Root;
}
}
}
}
void query(char *s) {
set<string> vis;
bool pnt = false;
Node *cur = Root;
while (*s) {
int idx = *(s++) - '';
while (cur && !cur->next[idx]) cur = cur->fail;
cur = cur ? cur->next[idx] : Root;
if (vis.find(cur->label) != vis.end()) continue;
if (cur->label.length()) {
if (!pnt) {
printf("Found key:");
pnt = true;
}
cout << ' ' << cur->label;
vis.insert(cur->label);
}
}
if (!pnt) puts("No key can be found !");
cout << endl;
}
} trie; char str[], buf[]; int main() {
// freopen("in", "r", stdin);
int n, m;
while (cin >> n >> m) {
trie = Trie();
gets(buf);
str[] = ;
while (n-- && gets(buf)) strcat(str, buf);
gets(buf);
while (m-- && gets(buf)) {
char *p = buf;
while (*(p++) != ']') ;
*(p++) = ;
while (*p == ' ') p++;
trie.insert(p, buf);
// cout << p << ' ' << buf << " inserted!"<< endl;
}
trie.build();
// cout << "built!!" << endl;
trie.query(str);
}
return ;
}

UPD:

 #include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string> using namespace std; const int HASHLEN = ;
const int M = ;
const int N = ;
string label[N], key[N];
bool vis[N];
int id[M];
char str[ * N], buf[N]; bool check(int t, char *p) {
int len = key[t].length();
for (int i = ; i < len; i++) {
if (key[t][i] != p[i]) return false;
}
return true;
} void work(char *p) {
bool pnt = false;
char *q = p;
int cur = , ep = ;
for (int i = ; i < HASHLEN - ; i++) cur = cur * + *(q++) - '', ep *= ;
while (*q && *p) {
// cout << cur << endl;
cur = cur * + *q - '';
cur %= ep;
int t = id[cur];
if (t != - && !vis[t]) {
if (check(t, p)) {
if (!pnt) printf("Found key:");
pnt = vis[t] = true;
cout << ' ' << label[t];
}
}
p++, q++;
}
if (!pnt) printf("No key can be found !");
cout << endl;
} int main() {
// freopen("in", "r", stdin);
int n, m;
while (cin >> n >> m) {
memset(id, -, sizeof(id));
memset(vis, , sizeof(vis));
gets(buf);
str[] = ;
while (n-- && gets(buf)) strcat(str, buf);
gets(buf);
for (int i = ; i < m; i++) {
gets(buf);
char *p = buf;
while (*p && *p != ']') p++;
*(++p) = ;
p++;
while (*p && *p == ' ') p++;
label[i] = buf;
key[i] = p;
// cout << label[i] << ' ' << key[i] << endl;
int cid = ;
for (int i = ; i < HASHLEN; i++) cid = cid * + p[i] - '';
// cout << cid << endl;
if (id[cid] != -) { puts("shit!"); while () ;}
id[cid] = i;
}
work(str);
}
return ;
}

  不知道为什么这个代码能过G++但是C++过不了,应该是代码里面有bug。另外,数据似乎跟描述的有点出入,说好的不同key值的前四位不会相同,可是写了句来试它的数据时就发现被骗了,所以后来用了5位,过了!

——written by Lyon

hdu 1277 全文检索 (直接映射查找 || 自动机)的更多相关文章

  1. hdu 1277 全文检索

    题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=1277 全文检索 Description 我们大家经常用google检索信息,但是检索信息的程序是很困难 ...

  2. HDU 1277全文检索(字典树)

    全文检索 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submi ...

  3. hdu 1277 全文检索 (字典树应用)

    全文检索 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submis ...

  4. hdu 2896 病毒侵袭 AC自动机(查找包含哪些子串)

    病毒侵袭 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submis ...

  5. hdu 2896 病毒侵袭 ac自动机

    /* hdu 2896 病毒侵袭 ac自动机 从题意得知,模式串中没有重复的串出现,所以结构体中可以将last[](后缀链接)数组去掉 last[]数组主要是记录具有相同后缀模式串的末尾节点编号 .本 ...

  6. hdu 1277 AC自动机入门(指针版和数组版)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1277 推荐一篇博客(看思路就可以,实现用的是java): https://www.cnblogs.co ...

  7. hdu 1277 AC自动机

    全文检索 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submis ...

  8. HDU 5164Matching on Array(AC自动机)

    这是BC上的一道题,当时比赛没有做,回头看看题解,说是AC自动机,想着没有写过AC自动机,于是便试着抄抄白书的模板,硬是搞了我数个小时2000ms时限1800过了= = ! 这里就直接贴上BC的结题报 ...

  9. hdu 2222 Keywords Search ac自动机入门

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2222 题意:有N(N <= 10000)个长度不超过50的模式串和一个长度不超过1e6的文本串. ...

随机推荐

  1. 【同余最短路】【例题集合】洛谷P3403 跳楼机/P2371 墨墨的等式

    接触到的新内容,[同余最短路]. 代码很好写,但思路不好理解. 同余最短路,并不是用同余来跑最短路,而是通过同余来构造某些状态,从而达到优化时间空间复杂度的目的.往往这些状态就是最短路中的点,可以类比 ...

  2. bzoj 1026 [SCOI2009]windy数——数位dp水题

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1026 迷恋上用dfs写数位dp了. #include<iostream> #in ...

  3. webpack学习之——Entry Points(入口起点)

    1.Entry property(entry属性) 1.1 Single Entry (Shorthand) Syntax(单个入口语法) 用法:entry: string | Array<st ...

  4. 理解nodejs的module

    module 在 Node.js 模块系统中,每个文件都视为独立的模块,node在运行某个模块儿时会生成一个module对象 Module { id: '.', exports: 2, parent: ...

  5. AudioToolbox.framework框架学习

    http://quding0308.iteye.com/blog/1596710 AudioFile AudioFileStream类 提供了一个接口,用来解析一个流音频文件. //创建一个new s ...

  6. Leetcode905.Sort Array By Parity按奇偶排序数组

    给定一个非负整数数组 A,返回一个由 A 的所有偶数元素组成的数组,后面跟 A 的所有奇数元素. 你可以返回满足此条件的任何数组作为答案. 示例: 输入:[3,1,2,4] 输出:[2,4,3,1] ...

  7. npm run dev 和 npm run serve

    1.ERR引发的思考 创建好的 vue 项目直接执行 vue run dev 报错?运行 vue run serve 就可以启动...如下 npm run dev npm ERR! missing s ...

  8. R语言数据分析利器data.table包—数据框结构处理精讲

    R语言数据分析利器data.table包-数据框结构处理精讲 R语言data.table包是自带包data.frame的升级版,用于数据框格式数据的处理,最大的特点快.包括两个方面,一方面是写的快,代 ...

  9. es安装遇到的问题

    问题1: es一闪即逝的问题?java的jdk环境变量没有配置好, JAVA_HOME没有配置好 必须在系统变量里面添加JAVA_HOME: C:\Program Files\Java\jre1.8. ...

  10. hadoop生态系统默认port集合

    版权声明:本文为博主John Lau原创文章.未经博主同意不得转载 https://blog.csdn.net/GreatElite/article/details/24651569      1 H ...