匹配统计
Posted lilibuxiangtle
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了匹配统计相关的知识,希望对你有一定的参考价值。
传送门:https://www.acwing.com/problem/content/162/(acwing有视频讲解,题解,数据之类的)
题意:给你两个字符串a和b,有q次询问,每次询问输出a的所有后缀和b恰好匹配长度为x的后缀个数。
题解:这个题好微妙啊,我换了两种思路都不太对。然后看了一下大雪菜老师的视频和(传送门)这个题解,豁然开朗。
先求出 b 串的 next 数组,然后a和b串进行匹配。a 串遍历用 i,b串用 j,j 正好是b串能匹配以 i 为结尾的a串的长度,所以就是以 i-j+1 为头的串。根据 kmp 中 next 数组的性质以 i-next[j]+1 的串和 b 恰好匹配的长度也为 j,然后依次套娃...直到 next[j]==-1 结束,用 res[j] 记录。但是这样套娃时间复杂度太大了O(nm)(菜鸡不会算嘤嘤嘤,借助大佬的时间复杂度),其实这就是一个拓扑的结构,只要最后记录完之后在算就会节省很多时间。res[x] 记录的是匹配的前缀至少为 x 的后缀数量,但我们要求的是恰好为x的数量,所以减去 res[x+1] 就是答案了。
1 #include<bits/stdc++.h> 2 using namespace std; 3 4 int nt[200100]; 5 int res[200100]; 6 map<int,int>p; 7 8 void getnext(string p) 9 { 10 nt[0]=-1; 11 int i=0,j=-1; 12 int len=p.size(); 13 while(i<len){ 14 if(j==-1||p[i]==p[j]){ 15 i++,j++; 16 nt[i]=j; 17 } 18 else j=nt[j]; 19 } 20 } 21 22 void kmp(string t,string p) 23 { 24 getnext(p); 25 int i=0,j=0; 26 int lt=t.size(),lp=p.size(); 27 while(i<lt){ 28 if(j==-1||t[i]==p[j]){ 29 i++,j++; 30 res[j]++; 31 } 32 else j=nt[j]; 33 } 34 } 35 36 int main() 37 { 38 ios::sync_with_stdio(false); 39 cin.tie(0); 40 cout.tie(0); 41 int n,m,t; 42 cin>>n>>m>>t; 43 string a,b; 44 cin>>a>>b; 45 kmp(a,b); 46 for(int i=n;i>=1;i--) res[nt[i]]+=res[i]; 47 while(t--){ 48 int x; 49 cin>>x; 50 cout<<res[x]-res[x+1]<<endl; 51 } 52 return 0; 53 }
以上是关于匹配统计的主要内容,如果未能解决你的问题,请参考以下文章
LeetCode 1773. 统计匹配检索规则的物品数量(5行核心代码)
[ jquery 文档处理 insertBefore(content) before(content|fn) ] 此方法用于把所有匹配的元素插入到另一个指定的元素元素集合的前面,实现外部插入(代码片段