zoj 3228 - Searching the String
来源:互联网 发布:animate软件 编辑:程序博客网 时间:2024/06/14 03:38
题目:给你一个长目标串str,和一些模式串,求每个串出现的次数。模式串有可覆盖和不可覆盖两种。
分析:字符串,多串匹配,AC自动机。由于数据有可能不允许相交,所以记录上一个的结束位置。
题目的数据比较猥琐,可能相同,采用一个 Fath域记录第一次出现的 id,计算一次就可以了。
说明:注意数据有相同的串;该题可以使用 RK算法+二分。
#include <stdio.h>#include <stdlib.h>#include <string.h>char Word[10];char Line[100005];int Walk[100005];int Fath[100005];/* AC_DFA define */#define nodesize 300005#define dictsize 26typedef struct node{ int flag[2]; int last; int deep; node* fail; node* next[dictsize];}tnode;tnode dict[nodesize];tnode* Q[nodesize];int ID[256];class AC_DFA{ private: int size; tnode* root; public: AC_DFA() {makeID();init();} void makeID() { for (int i = 0 ; i < dictsize ; ++ i) ID[i+'a'] = i; } void init() { memset(dict, 0, sizeof(dict)); root=NULL;size=0;root=newnode(); } tnode* newnode() { dict[size].fail = root; dict[size].last = -1; return &dict[size ++]; } void insert(char* word, int id, int s) { tnode* now = root; for (int i = 0 ; word[i] ; ++ i) { if (!now->next[ID[word[i]]]) now->next[ID[word[i]]] = newnode(); now = now->next[ID[word[i]]]; } /* 记录数据,相同的计入父节点 */if (!now->flag[s]) {now->deep = strlen(word);now->flag[s] = id;}else Fath[id] = now->flag[s]; } void setfail() { Q[0] = root; root->fail = NULL; for (int move = 0,save = 1 ; move < save ; ++ move) { tnode* now = Q[move]; for (int i = 0 ; i < dictsize ; ++ i) if (now->next[i]) { tnode* p = now->fail; while (p && !p->next[i]) p = p->fail; now->next[i]->fail = p?p->next[i]:root; Q[save ++] = now->next[i]; }else now->next[i] = now==root?root:now->fail->next[i];//构建 Trie图 } } int query(char* line, int N) { memset(Walk, 0, sizeof(Walk)); tnode* now = root; for (int i = 0 ; line[i] ; ++ i) { now = now->next[ID[line[i]]]; for (tnode* p = now ; p ; p = p->fail) { if (p->flag[0]) ++ Walk[p->flag[0]]; if (p->flag[1] && p->last+p->deep <= i) { p->last = i; ++ Walk[p->flag[1]]; }} } for (int i = 1 ; i <= N ; ++ i) printf("%d\n",Walk[Fath[i]]); return 0; }};/* AC_DFA end */int main(){ int N,S,T = 1; AC_DFA ac; while (scanf("%s",Line) != EOF) { ac.init(); scanf("%d",&N); for (int i = 1 ; i <= N ; ++ i) { scanf("%d %s",&S,Word); Fath[i] = i; ac.insert(Word, i, S); } ac.setfail(); printf("Case %d\n",T ++); ac.query(Line, N); printf("\n"); } return 0;}
0 0
- zoj 3228 Searching the String
- zoj 3228 Searching the String
- zoj 3228 Searching the String
- zoj 3228 Searching the String
- zoj 3228 - Searching the String
- ZOJ 3228Searching the String
- zoj 3228 Searching the String【ac自动机】
- ZOJ 3228 Searching the String(AC自动机)
- ZOJ 3228 Searching the String(AC自动机)
- zoj -- 3228 Searching the String(AC自动机)
- ZOJ - 3228 Searching the String (AC自动机)
- zoj 3228 Searching the String(AC自动机)
- ZOJ 3228 Searching the String AC自动机
- zoj 3228 Searching the String (ac自动机)
- zoj 3228 Searching the String(trie)
- zoj 3228 Searching the String 【AC自动机】
- ZOJ 3228 Searching the String(AC自动机)
- ZOJ Problem Set - 3228 Searching the String AC自动机
- Matlab绘图-很详细,很全面
- 如何用OpenStack安全构建私有云?
- 修改ubutun控制台颜色
- 关于MAC下的QQ聊天中看不到对方所发的图片解决
- 玩转日期时间
- zoj 3228 - Searching the String
- Unicode
- gbk/gb18030/gb2312/utf-8
- 【好程序员特训营】IO常用流的功能及特性
- POJ 3414 Pots
- IOS开发之证书共享(团队协同开发)
- 蓝牙核心-链路管理相关概念
- unity网络编程学习(2)聊天室
- Fighting for HDU