字符串专题:HDU2222——多串匹配

来源:互联网 发布:2017年java工程师工资 编辑:程序博客网 时间:2024/06/05 19:29

题目描述:

         给出n个模板串,然后给一个长串,问模板串在长串中出现了多少个。

大致思路:

         应该是一个典型的模板题,用AC自动机就可以搞定。

         但是,鉴于最近学了字符串哈希,那么就有了一个哈希的想法。首先计算每个模板串的哈希值,存到一个哈希表中,然后枚举每一个模板串的长度,把长串该长度的所有子串哈希值计算出来,判断是否出现在哈希表中,如果出现的话就把答案加一。但是字符串哈希之后实在是不会怎么用hashmap优化,所以只写出了用AC自动机的做法……当然,AC自动机还是很局限的,因为Trie不可能构造的过大,所以对于字符串匹配来说还是没法满足大多数需求的。

代码:

#include <cstdio>#include <cstring>#include <queue>#include <iostream>#include <algorithm> using namespace std; const int M = 510000; struct Trie {   int ch[M][26],fail[M],end[M],cnt,root;    int NewNode() {       ++cnt;       memset(ch[cnt],-1,sizeof(ch[cnt]));       end[cnt] = 0;       fail[cnt] = -1;        return cnt;    }   void init() {       cnt = 0; root = NewNode();    }   void insert(char s[]) {       int len = strlen(s), pos = root;       for (int i = 0; i<len; i++) {           int val = s[i]-'a';           if (ch[pos][val] == -1) ch[pos][val] = NewNode();           pos = ch[pos][val];       }       end[pos]++;    }   queue<int> Q;   void get_fail() {       fail[root] = root;       for (int i = 0; i<26; i++)           if (ch[root][i] == -1) ch[root][i] = root;           else {                fail[ch[root][i]] = root;                Q.push(ch[root][i]);           }       while (!Q.empty()) {           int pos = Q.front(); Q.pop();           for (int i = 0; i<26; i++)                if (ch[pos][i] == -1)ch[pos][i] = ch[fail[pos]][i];                else {                    fail[ch[pos][i]] =ch[fail[pos]][i];                    Q.push(ch[pos][i]);                }       }    }   int query(char s[]) {       int len = strlen(s), pos = root,ans = 0;       for (int i = 0; i<len; i++) {           int tmp = ch[pos][s[i]-'a']; pos = tmp;           while (tmp!=root) {                ans += end[tmp]; end[tmp] = 0;tmp = fail[tmp];           }       }        return ans;    }}AC; char s1[1100000]; int main() {   int t,n;   cin>>t;   while (t--) {       scanf("%d",&n);       AC.init();       for (int i = 1; i<=n; i++) {           scanf("%s",s1);           AC.insert(s1);       }       AC.get_fail();        scanf("%s",s1);       printf("%d\n",AC.query(s1));    }}

0 0
原创粉丝点击