Keywords Search

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 25356    Accepted Submission(s): 8280

Problem Description
In the modern time, Search engine came into the life of everybody like Google, Baidu, etc. Wiskey also wants to bring this feature to his image retrieval system. Every image have a long description, when users type some keywords to find the image, the system will match the keywords with description of image and show the image which the most keywords be matched. To simplify the problem, giving you a description of image, and some keywords, you should tell me how many keywords will be match.
 
Input
First line will contain one integer means how many cases will follow by. Each case will contain two integers N means the number of keywords and N keywords follow. (N <= 10000) Each keyword will only contains characters 'a'-'z', and the length will be not longer than 50. The last line is the description, and the length will be not longer than 1000000.
 
Output
Print how many keywords are contained in the description.
 
Sample Input
1 5 she he say shr her yasherhs
 
Sample Output
3
text:100万长度,关键字1万,多个测试案例,用Trie匹配必定超时。Trie也可以多模式匹配,不多比AC自动机耗时太多。
Trie 超时代码:
 #include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <iomanip>
#include <cstdlib>
using namespace std;
const int INF=0x5fffffff;
const int MS=;
const double EXP=1e-; struct node
{
int have;//根据情况灵活变化
node * next[];
}nodes[MS*]; //注意这个大小 尽量大一点 node *root;
int cnt,ans; char text[MS*]; node * add_node(int c)
{
node *p=&nodes[c];
for(int i=;i<;i++)
p->next[i]=NULL;
p->have=;
return p;
} void insert(char *str)
{
node *p=root;
int len=strlen(str);
for(int i=;i<len;i++)
{
int id=str[i]-'a';
if(p->next[id]==NULL)
{
p->next[id]=add_node(cnt++);
}
p=p->next[id];
}
p->have++;
}
void search(char *str)
{
node *p=root;
int len=strlen(str);
for(int i=;i<len;i++)
{
int id=str[i]-'a';
p=p->next[id];
if(p==NULL)
return ;
if(p->have)
{
ans+=p->have;
p->have=;
}
}
} int main()
{
int n,i,T;
scanf("%d",&T);
while(T--)
{
cnt=;
ans=;
root=add_node(cnt++);
scanf("%d",&n);
for(i=;i<n;i++)
{
scanf("%s",text);
insert(text);
}
scanf("%s",text);
int len=strlen(text);
for(i=;i<len;i++)
{
search(text+i);
}
printf("%d\n",ans);
}
return ;
}

这题是AC自动机最经典的入门题。学会了kmp,Trie,就可以学习ac自动机了。

time : 280 ms

 #include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <iomanip>
#include <cstdlib>
using namespace std;
const int INF=0x5fffffff;
const int MS=;
const double EXP=1e-;
// AC自动机 KMP TRIE
struct node
{
bool isbad;
node *pre;
node * next[];
int n;
}nodes[MS*]; //注意这个大小 个数*每个的长度就不会访问非法内存 node *root;
int cnt,ans; char text[MS*]; node * add_node(int c)
{
node *p=&nodes[c];
for(int i=;i<;i++)
p->next[i]=NULL;
p->isbad=false;
p->pre=NULL;
p->n=;
return p;
} void insert(char *str)
{
node *p=root;
int len=strlen(str);
for(int i=;i<len;i++)
{
int id=str[i]-'a';
if(p->next[id]==NULL)
{
p->next[id]=add_node(cnt++);
}
p=p->next[id];
}
p->isbad=true;
p->n++; //终止节点
} void build()
{ // 在trie树上加前缀指针
for(int i=;i<;i++)
nodes->next[i]=root;
nodes->pre=NULL;
root->pre=nodes;
deque<node *> dq;
dq.push_back(root);
while(!dq.empty())
{
node *proot=dq.front();
dq.pop_front();
for(int i=;i<;i++)
{
node *p=proot->next[i];
if(p!=NULL)
{
node *pre=proot->pre;
while(pre)
{
if(pre->next[i]!=NULL) //NULL==0
{
p->pre=pre->next[i];
if(p->pre->isbad)
p->isbad=true;
break;
}
else
pre=pre->pre;
}
dq.push_back(p);
}
}
}
} void search(char *str)
{ //返回值为true,说明包含模式串
node *p=root;
int len=strlen(str);
for(int i=;i<len;i++)
{
int id=str[i]-'a';
while(p!=root&&p->next[id]==NULL)
{
p=p->pre;
}
p=p->next[id];
if(p==NULL)
{
p=root;
}
node *tp=p;
while(tp!=root&&tp->n!=)
{
ans+=tp->n;
tp->n=;
tp=tp->pre;
} /*
while(1) 是否包含模式串
{
if(p->next[id])
{
p=p->next[id];
if(p->isbad)
return true;
break;
}
else
p=p->pre;
}
*/
} //return false;
} int main()
{
int n,T;
scanf("%d",&T);
while(T--)
{
cnt=;
ans=;
add_node(cnt++);
root=add_node(cnt++);
scanf("%d",&n);
for(int i=;i<n;i++)
{
scanf("%s",text);
insert(text);
}
build();
scanf("%s",text);
search(text);
printf("%d\n",ans);
}
return ;
}
/*
节点p的前缀指针定义为:指向树中出现
过的S的最长的后缀(不能等于S)。
如果p节点匹配失败,该节点对应c,就沿着它的父节点的前缀指针走,直到某节点,其儿子节点
对应的字母也为c,把p节点的前缀指针指向该儿子节点。如果走到了root都没有找到,就指向root
*/
 
 

Keywords Search的更多相关文章

  1. 【HDU2222】Keywords Search AC自动机

    [HDU2222]Keywords Search Problem Description In the modern time, Search engine came into the life of ...

  2. hdu2222 Keywords Search ac自动机

    地址:http://acm.split.hdu.edu.cn/showproblem.php?pid=2222 题目: Keywords Search Time Limit: 2000/1000 MS ...

  3. HDU 2222 Keywords Search(AC自动机模版题)

    Keywords Search Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others ...

  4. HDU2222 Keywords Search [AC自动机模板]

    Keywords Search Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others ...

  5. C++之路进阶——hdu2222(Keywords Search)

    /*Keywords Search Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others) ...

  6. HDU 2222 Keywords Search(查询关键字)

    HDU 2222 Keywords Search(查询关键字) Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K ...

  7. hdu----(2222)Keywords Search(ac自动机)

    Keywords Search Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)T ...

  8. hdu----(2222)Keywords Search(trie树)

    Keywords Search Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)T ...

  9. hdu 2222 Keywords Search ac自己主动机

    点击打开链接题目链接 Keywords Search Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Ja ...

随机推荐

  1. MYSQL数据库性能调优之二:定位慢查询

    windows下开启慢查询: 第一步:先查看版本 第二步查看查询日志和慢查询配置 第三步:配置开启慢查询 在my.ini配置文件的[mysqld]选项下增加: slow_query_log=TRUE ...

  2. Hadoop学习笔记(2)

    Hadoop学习笔记(2) ——解读Hello World 上一章中,我们把hadoop下载.安装.运行起来,最后还执行了一个Hello world程序,看到了结果.现在我们就来解读一下这个Hello ...

  3. C#下载http文件

    @(编程) using System; using System.IO; using System.Net; namespace Wisdombud.Util { public class HttpH ...

  4. NHibernate的简单例子

    NHibernate的简单例子 @(编程) [TOC] 因为项目需求,搭了一个NHibernate的例子,中间遇到了一些问题,通过各种方法解决了,在这里记录一下最后的结果. 1. 需要的dll Com ...

  5. jgroups 入门

    官网地址:http://www.jgroups.org/ 聊天室示例:http://www.jgroups.org/tutorial/html/ch02.html 2.1. JGroups overv ...

  6. android adb服务启动不了解决办法

    当然还有可能是其它的原因,下面是一些解决办法的汇总 因为在对应的文件夹下找不到adb的问题,将android-sdk/platform-tools和android-sdk/tools都加到环境变量中去 ...

  7. 结构类模式(二):桥接(Bridge)

    定义 将抽象化(Abstraction)与实现化(Implementation)脱耦,使得二者可以独立地变化. 在软件系统中,某些类型由于自身的逻辑,它具有两个或多个维度的变化,那么如何应对这种“多维 ...

  8. Redis总结(五)缓存雪崩和缓存穿透等问题

    前面讲过一些redis 缓存的使用和数据持久化.感兴趣的朋友可以看看之前的文章,http://www.cnblogs.com/zhangweizhong/category/771056.html .今 ...

  9. C# Hashtable 简述

    一,哈希表(Hashtable)简述 在.NET Framework中,Hashtable是System.Collections命名空间提供的一个容器,用于处理和表现类似keyvalue的键值对,其中 ...

  10. easyui grid中翻页多选方法

    <table class="easyui-datagrid" title="人员选择" id="dg" data-options=&q ...