欢迎访问 生活随笔!

生活随笔

当前位置: 首页 >

KMP模式串匹配+Compress Words CodeForces - 1200E

发布时间:2023/12/4 52 豆豆
生活随笔 收集整理的这篇文章主要介绍了 KMP模式串匹配+Compress Words CodeForces - 1200E 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

题意:

给你若干个字符串,答案串初始为空。第 iii 步将第 iii 个字符串加到答案串的后面,但是尽量地去掉重复部分(即去掉一个最长的、是原答案串的后缀、也是第 iii个串的前缀的字符串),求最后得到的字符串。
字符串个数不超过 10510^5105,总长不超过 10610^6106

题目:

Amugae has a sentence consisting of n words. He want to compress this sentence into one word. Amugae doesn’t like repetitions, so when he merges two words into one word, he removes the longest prefix of the second word that coincides with a suffix of the first word. For example, he merges “sample” and “please” into “samplease”.

Amugae will merge his sentence left to right (i.e. first merge the first two words, then merge the result with the third word and so on). Write a program that prints the compressed word after the merging process ends.

Input

The first line contains an integer n (1≤n≤105), the number of the words in Amugae’s sentence.

The second line contains n words separated by single space. Each words is non-empty and consists of uppercase and lowercase English letters and digits (‘A’, ‘B’, …, ‘Z’, ‘a’, ‘b’, …, ‘z’, ‘0’, ‘1’, …, ‘9’). The total length of the words does not exceed 106.

Output

In the only line output the compressed word after the merging process ends as described in the problem.

Examples
Input

5
I want to order pizza

Output

Iwantorderpizza

Input

5
sample please ease in out

Output

sampleaseinout

分析:

KMP:从第二个开始字符串开始和前面合并的子串进行kmp算法
注意每次匹配的起点位置,应该为 文本串长度-模式串长度
哈希:每次需要求最长的、是原答案串的后缀、也是第 iii个串的前缀的字符串。枚举这个串的长度,哈希比较即可。

AC代码:

KMP:

#include<bits/stdc++.h> using namespace std; const int M=1e6+10; string a,b; int nx[M]; int len,l2;void getnext() {int k = -1, j = 0;nx[0] = -1;while(j<l2){if(k==-1||b[j]==b[k])nx[++j]=++k;elsek=nx[k];} } int KMP(int st) {int i=st,j=0;getnext();while(i<len){if(j==-1 || a[i]==b[j]) ++i,++j;else j=nx[j];}return j; }int main() {int t;scanf("%d",&t);cin>>a;len=a.size();int pos=0;for(int i=1; i<t; i++){cin>>b;l2=b.size();int x=KMP(max(pos-l2,0));for(int i=x; i<l2; i++){a.push_back(b[i]);len++;}pos=len;}cout<<a<<endl; }

哈希

#include <bits/stdc++.h> using namespace std; typedef long long ll;const int N=1e6+10;ll mo[3]={(ll)1e9+21,(ll)1e9+9,(ll)1e9+7}; ll ba[3]={233,223,23}; ll p[3][N]; ll ha[3][N]; void init(){p[0][0]=p[1][0]=p[2][0]=1;for(int i=1; i<N; ++i){p[0][i]=(p[0][i-1]*ba[0])%mo[0];p[1][i]=(p[1][i-1]*ba[1])%mo[1];p[2][i]=(p[2][i-1]*ba[2])%mo[2];} } ll cal(int x,int l,int r){ll tp=(ha[x][r]-ha[x][l-1]*p[x][r-l+1])%mo[x];return (tp+mo[x])%mo[x]; }char c1[N],c2[N]; int getsr(int x,int n){int sr=1;ll d1=0,d2=0,d3=0;for(int i=n,j=1; i>=x; --i,++j){d1=(d1*ba[0]+c2[j])%mo[0];d2=(d2*ba[1]+c2[j])%mo[1];d3=(d3*ba[2]+c2[j])%mo[2];if(cal(0,i,n)==d1 && cal(1,i,n)==d2 && cal(2,i,n)==d3){sr=j+1;}}return sr; }int main() {init();int n;scanf("%d %s",&n,c1+1);int len=strlen(c1+1);for(int i=1; i<=len; ++i){ha[0][i]=(ha[0][i-1]*ba[0]+c1[i])%mo[0];ha[1][i]=(ha[1][i-1]*ba[1]+c1[i])%mo[1];ha[2][i]=(ha[2][i-1]*ba[2]+c1[i])%mo[2];}for(int i=1; i<n; ++i){scanf("%s",c2+1);int t1=strlen(c2+1);int sr=getsr(max(len-t1+1,1),len);for(int i=sr; i<=t1; ++i){++len;c1[len]=c2[i];ha[0][len]=(ha[0][len-1]*ba[0]+c1[len])%mo[0];ha[1][len]=(ha[1][len-1]*ba[1]+c1[len])%mo[1];ha[2][len]=(ha[2][len-1]*ba[2]+c1[len])%mo[2];}}printf("%s\n",c1+1);return 0; }

总结

以上是生活随笔为你收集整理的KMP模式串匹配+Compress Words CodeForces - 1200E的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。