E. Compress Words

题目
E. Compress Words
time limit per test1 second
memory limit per test256 megabytes
inputstandard input
outputstandard output
Amugae has a sentence consisting of nn 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 nn (1≤n≤1051≤n≤105), the number of the words in Amugae’s sentence.

The second line contains nn 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 106106.

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
sampleaseinout

题意:给出n个单词,将单词两两合并,去掉最长相同前后缀。
思路:先kmp找出需要匹配单词的next数组,再与当前字符串进行连接。

/**/
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+5;
int t[N];
char s[N],p[N];
int len1,len2;
void next(char *p)//(数组名不要用next,会与c++库函数重复,CE)
{
    int j,i;
    j=-1;
    t[0]=-1;
    i=0;
    while(i<len2-1)
    {
        if(j==-1||p[i]==p[j])
        {
            i++;
            j++;
            if(p[i]!=p[j])
            {
                t[i]=j;
            }
            else
                t[i]=t[j];
        }
        else
            j=t[j];
    }
}
int kmp(char *s,char *p)
{
    int i,j;
    i=max(0,len1-len2);
    j=0;
    next(p);
    for(;i<len1;)
    {
        while(s[i]!=p[j])//当失配时,开始考虑next数组
        {
            if(t[j]==0)//如果子串中没有前后缀,子串从头开始匹配
            {
                j=0;
                break;
            }
            else//子串有最大相同前后缀,j从next[j]处重新开始匹配
                j=t[j];
        }
        if(s[i]==p[j])
        {
            j++;
        }
        i++;
    }
    return j;//结束条件不同,模板kmp是判断j是判断j==len;这一个是走遍母串去找子串的位置
}
int main()
{
    int n,i,j;
    cin>>n;
    cin>>s;
    n-=1;
    len1=strlen(s);
    while(n--)
    {
        cin>>p;
        len2=strlen(p);
        int c=kmp(s,p);
        i=len1-c;
        for(j=0;j<len2;j++)
        {
            s[i++]=p[j];
        }
        s[i]='\0';
        len1+=len2-c;
    }
    cout<<s<<endl;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值