zoukankan      html  css  js  c++  java
  • KMP+差分 文章过滤器 (filter)

    Description

    给定一些短串,要求你在一个长串中,将这些短串部分变为(*)

    Input

    第一行包括一个整数(n),表示短串的数量.

    接下来的(n)行,为(n)个短串.

    最后一行,为你需要变化的长串.

    Output

    一行,表示变化后的长串.

    PS:长串会有中有各种字符,短串仅包含英文字符

    样例输入

    3

    int

    ing

    kitty

    Int is interesting! ~OwO~

    样例输出

    (***) is (***)erest(***)ing! ~OwO~

    上面的一些输入输出中为全角,实际上为半角.

    这题做法有很多啊,可以哈希,可以AC自动机,可以KMP.

    这里讲一下KMP算法.

    做法为(KMP+)差分.

    首先需要将长串中的字母全部转为小写(大写).

    (isalpha)吼啊

    我们对每一个短串求出其(next)数组.再枚举这些串去和长串匹配.

    但是一些位置会出问题.

    比如

    给定两个短串为(GRE)(eat),长串为(Great)

    则我们的长串要变成(*****)

    因此引入了差分.

    如果匹配上之后,我们直接对其左端点和右端点(+1)差分。

    最终枚举的话,直接判断有无标记,如果有,则将当前位置变为(*)

    然后直接输出即可.

    代码

    #include<cstdio>
    #include<cctype>
    #include<cstring>
    #define R register
    using namespace std;
    char sta[150008],stb[150008];
    int pos[150008],k,n,len;
    struct cod
    {
    	int nex[55],len;
    	char s[55];
    }str[55];
    char st[55],c;
    inline char ch(char s)
    {
    	if(!isalpha(s))return s;
    	if(s<='Z' and s>='A')s=s-'A'+'a';
    	return s;
    }
    int main()
    {
        scanf("%d",&n);
    	for(R int i=1;i<=n;i++)
    	{
    		scanf("%s",st+1);
    		str[i].len=strlen(st+1);
    		for(R int j=1;j<=str[i].len;j++)
    			str[i].s[j]=ch(st[j]);
    		str[i].nex[1]=0;k=0;
    		for(R int j=2;j<=str[i].len;j++)
    		{
    			while(str[i].s[k+1]!=str[i].s[j] and k)k=str[i].nex[k];
    			if(str[i].s[k+1]==str[i].s[j])k++;
    			str[i].nex[j]=k;
    		}
    	}
        getchar();
    	while(c!='
    ')
    	{
    		c=getchar();
    		if(c=='
    ')break;
    		sta[++len]=c;
    		stb[len]=ch(c);
    	}
    	for(R int i=1;i<=n;i++)
    	{
    		k=0;
    		for(R int j=1;j<=len;j++)
    		{
    			while(k and str[i].s[k+1]!=stb[j])k=str[i].nex[k];
    			if(str[i].s[k+1]==stb[j])k++;
    			if(k==str[i].len)
    			{
    				pos[j-str[i].len+1]++;
    				pos[j+1]--;
    			}
    		}
    	}
    	for(R int i=1;i<=len;i++)
    	{
    		pos[i]+=pos[i-1];
    		if(pos[i])sta[i]='*';
    		printf("%c",sta[i]);
    	}
    }
    /*
    2
    GRE 
    eat
    Great Britain
    ***** Britain
    */
    
  • 相关阅读:
    第4次作业(条件)比较大小。第3次作业(条件)计算火车运行时间。
    GitHub搜索技巧
    flex实现左中固定不变,右边自适应
    JavaScript高级__原型继承+组合继承
    JavaScript高级__深入了解闭包
    JavaScript高级__执行上下文代码案例
    JavaScript中的显式原型链 prototype 和隐式原型 __proto__
    谷歌强大插件收集,持续更新。。。
    js中~~和^=
    vue自定义指令----directive
  • 原文地址:https://www.cnblogs.com/-guz/p/9829149.html
Copyright © 2011-2022 走看看