FZU 2122(KMP)

2024-08-27 14:58
文章标签 kmp fzu 2122

本文主要是介绍FZU 2122(KMP),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

/*FZU 2122(简单字符串匹配,KMP算法)
题目大意:
就是给你3个字符串,第一个是模式串(用该串在文本串中去查找与之相同的串)即子串,
第二个字符串是去替换在文本串(即主串)已找到相同的子串,从而最后输出产生的新串,
如果没有找到,就原样输出文本串(即主串),第三个字符串就是文本串(即主串)个人解题思想:
就是用KMP算法找到子串在主串中的位置,然后首先用相同字符“~”去替换主串中找到的子串;
运行产生的效果如下:
输入:
abc
bc ab
aaa aaabca 333Abcc##
输出:
aaa aa~~~a 333~~~c##
再用一个for循环去扫描,如果出现‘~’,就立即输出需要替换上去的字符串,同时i=i+l2(l2为子串的长度);
最终输出结果:
输入:
abc
bc ab
输出:
aaa aabc aba 333bc abc##
*/
# include<iostream>
# include<cstdio>
# include<cstring>
# include<algorithm>
# include<cstdlib>
# include<string>
# include<cmath>
using namespace std;
int next[108];
char p[108];
char s[50008];
char s1[1009];
int l1,l2,l3;
int i,j;
int ans;
void getnext()//KMP固定模板算法求next数组,这是KMP算法的核心
{next[0]=-1;int i=0;int h=-1;while(i<l2){if(h==-1||p[i]==p[h]||p[i]+32==p[h]||p[i]==32+p[i])//这里需注意大写小写都有为了统一全都变成小写{i++;h++;next[i]=h;}elseh=next[h];}
}
void kmp(int n)//KMP函数
{i=n,j=0;while(i<l1&&j<l2){if(j==-1||s[i]==p[j]||p[j]+32==s[i]||p[j]-32==s[i])//同上{i++;j++;}elsej=next[j];if(j==l2){ans=i-l2;for(i=ans;i<ans+l2;i++){s[i]='~';//!!!!此处需要注意,该字符不能随便取,应取ASCII在[32,125]区间外的//表示刚开始没看清题目,以为随便取,就取了‘*’结果WA 15次痛心呀,后来改成‘~’(ASCII为126)就AC了}j=next[j];}}}
int main()
{while(gets(p)){gets(s1);gets(s);l1=strlen(s);l2=strlen(p);getnext();kmp(0);for(i=0;i<l1;){if(s[i]=='~') {printf("%s",s1);i+=l2;}else {cout<<s[i];i++;}}cout<<endl;}return 0;
}
/*
体会:
虽然这道题WA 15次 但是最后还是被我弄明白了,感觉还是不错的。故此下次一定要看清题目
*/

这篇关于FZU 2122(KMP)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1111999

相关文章

codeforces535D:Tavas and Malekas(KMP)

(i-1 , i)有重合的时候 ,从第i位开始的子串必须是模式串的前缀。 而同时,从第i位开始的子串本来就已经是模式串的后缀了。 typedef long long LL ;const int maxn = 1000008 ;int next[maxn] ;void getnext(char s[]){int len = strlen(s) ;next[0] = -1 ;i

fzu 2277 Change 线段树

Problem 2277 Change Time Limit: 2000 mSec    Memory Limit : 262144 KB  Problem Description There is a rooted tree with n nodes, number from 1-n. Root’s number is 1.Each node has a value ai.

fzu 2275 Game KMP

Problem 2275 Game Time Limit: 1000 mSec    Memory Limit : 262144 KB  Problem Description Alice and Bob is playing a game. Each of them has a number. Alice’s number is A, and Bob’s number i

KMP 详解

KMP数组存的是什么 对于一个字符串 b,下标从1开始。 则kmp[i]表示 以i结尾的连续子串 = s的前缀的最大值(等价于前缀最大结尾处) 如何求KMP 假设 i 以前的KMP都被求出来了。 j 表示上一个字符可以成功匹配的长度(等价于下标) 如果b[j+1] != b[i]下一个位置匹配不上(即不能成为前缀) 则,让j = kmp[j] 即成为以j结尾的 连续子串 的 最长前缀

KMP算法详解 --- 彻头彻尾理解KMP算法

前言     之前对kmp算法虽然了解它的原理,即求出P0···Pi的最大相同前后缀长度k。   但是问题在于如何求出这个最大前后缀长度呢?   我觉得网上很多帖子都说的不是很清楚,总感觉没有把那层纸戳破,   后来翻看算法导论32章 字符串匹配,虽然讲到了对前后缀计算的正确性,但是大量的推理证明不大好理解,没有与程序结合起来讲。   今天我在这里讲一讲我的一些理解,希望大家多多指教

扩展KMP --- HDU 3613 Best Reward

Best Reward Problem's Link:   http://acm.hdu.edu.cn/showproblem.php?pid=3613   Mean:  给你一个字符串,每个字符都有一个权值(可能为负),你需要将这个字符串分成两个子串,使得这两个子串的价值之和最大。一个子串价值的计算方法:如果这个子串是回文串,那么价值就是这个子串所有字符权值之和;否则价值为0。

【FZU】1921 栀子花开 线段树果题

Problem 1921 栀子花开 Accept: 216    Submit: 745 Time Limit: 1000 mSec    Memory Limit : 32768 KB Problem Description 这是一个栀子花开的季节,也是一个离别的季节,四年一千多个日日夜夜,那校园的角角落落,留下了我们沉思的身影;那上百次的成绩排名表,印证了我们深深浅浅不断进步的

【FZU】2171 防守阵地 II 线段树

Problem 2171 防守阵地 II Accept: 96    Submit: 360 Time Limit: 3000 mSec    Memory Limit : 32768 KB Problem Description 部队中总共有N个士兵,每个士兵有各自的能力指数Xi,在一次演练中,指挥部确定了M个需要防守的地点,指挥部将选择M个士兵依次进入指定地点进行防守任务,获得

【FZU】2105 Digits Count 线段树

传送门:【FZU】2105 Digits Count 题目分析:与、或、异或三种操作都是每一位相互独立的,所以可以将线段树建四棵,分别对应一位,and和or操作相当于覆盖操作,xor操作相当于反转操作,就和普通的线段树方法类似,设立两个lazy标记即可。查询的时候求得每一位的1的个数*权重(1,2,4,8),全部累加就是答案。 代码如下: #include <cst

数据结构串的实现以及KMP改进算法

</pre><pre name="code" class="cpp">#include <stdio.h>#include <stdlib.h>#define OK 1#define ERROR 0#define TRUE 1#define FALSE 0#define MAXSIZE 40 /* 存储空间初始分配量 */typedef int Status; /* Status是