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. TreeSet介绍

    一.TreeSet原理: 1.TreeSet存储对象的时候, 可以排序, 但是需要指定排序的算法 2.Integer能排序(有默认顺序), String能排序(有默认顺序), 自定义的类存储的时候出现 ...

  2. Dagger2 scope

    1. 一个没有scope的component是不能依赖于另外一个有scope的component 2.@Singleton不是真正意义的单例,比如下面 @Singleton @Component cl ...

  3. sql操作table

    1.增加表字段 alter table tbsptrustquotdoc(表名)  add  chargeapplystate(字段名) char(1)(类型) default '1'(默认值) 2. ...

  4. C++11对象构造的改良

    [C++11对象构造的改良] C++03中一个构造函数无法构造另一个构造函数,因为A()实际上意味着生成一个临时对象,存在语音混淆.详情请看参考2. C++11中允许直接在初始化列表中调用其它的构造函 ...

  5. [iOS微博项目 - 2.3] - 用户取消对app的授权

    github: https://github.com/hellovoidworld/HVWWeibo   A.用户取消对app的授权 用户可以在微博网站上取消对某个应用(app)的授权   1.打开& ...

  6. HDU2948Geometry Darts(简单计算几何)

    题目大意就是说两个人掷飞镖,飞镖在所给定的图形内就记一分,现在给定N个图形(圆.三角形和矩形),问每一次比赛(没人分别掷三次)谁赢. #include <map> #include < ...

  7. css div 垂直居中

    参考:http://css-tricks.com/centering-in-the-unknown/ <style> .valign { font-size: 0px;/* clear s ...

  8. mysql无法启动 mysqld process already exists

    1.提示:A mysqld process already exists ps 命令用于查看当前正在运行的进程. grep 是搜索 例如: ps -ef | grep mysql 表示查看所有进程里 ...

  9. 数据库:mongodb与关系型数据库相比的优缺点

      与关系型数据库相比,MongoDB的优点:①弱一致性(最终一致),更能保证用户的访问速度:举例来说,在传统的关系型数据库中,一个COUNT类型的操作会锁定数据集,这样可以保证得到“当前”情况下的精 ...

  10. C++学习之const整理总结

    1什么是const? (const类型)常类型是指使用类型修饰符const说明的类型,常类型的变量或对象的值是不能被更新的.(但可以偷梁换柱进行更新) 2为什么引入const? const 推出的初始 ...