基于改进型KMP算法的字符串查找与替换
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
数据结构实验报告
知识范畴:串完成日期:2016年04月6日
实验题目:基于改进型KMP算法的字符串查找与替换
实验内容及要求:
从键盘输入三个字符串s、a、b,在串s中查找子串a,并将串s中的所有a替换为b,输出替换以后的串。注意:a和b的串长不要求相等;若s中无子串a,输出结果与串s相同。实验目的:掌握字符串模式匹配的KMP算法。
数据结构设计简要描述:
用char型数组储存串s,a,b。用int型数组储存模式串a的next数组。
算法设计简要描述:
在串s中查找子串a的起始位置使用了KMP算法。利用get_nextval函数得到模式串a的nextval数组。函数replace替换s中的a。用指向s的指针p先指向s起始地址,利用KMP 算法得到s中第一个a起始位置,然后用b替换a,替换后p指向第一个a起始位置再向后b 的长度,查找第二个a的起始位置,依次类推。
输入/输出设计简要描述:
按照提示:先输入s串,然后输入a串。
如果未找到a,则原样输出s。
如果找到第一个a,输出第一个a的位置,并提示输入b,然后会替换剩下的
所有a,输出替换后的s,并输出替换次数。
编程语言说明:
使用Visual C++编程。主要代码采用C语言实现;动态存储分配采用C++的new和delete操作符实现;输入与输出采用C++的cin和cout流;程序注释采用C/C++规范。
主要函数说明:
void get_nextval(char *t, int nextval[]); //get_nextval函数
int index_kmp(char *s, char *t, int next[]); //KMP算法
void replace(char *s, char *b, int position, int lena);//替换字符串函数: //b的长度大于a的情况下先将s中a后边的所有字符向后挪动lenb-lena个位置
//b的长度小于a的情况下先将s中a后边的所有字符向前挪动lena-lenb个位置
//然后将a的字符逐个用b中的字符替换
程序测试简要报告:
(1)无a测试
程序输入输出
结论
程序输出结果与期望输出结果相符。
(2)a、b等长度测试
程序输入输出
结论
程序输出结果与期望输出结果相符。
(3)a、b不等长度测试
程序输入输出
结论
程序输出结果与期望输出结果相符。
源程序代码:
#include
#include
using namespace std;
void get_nextval(char *t, int nextval[]) {//get_nextval函数
int j = 1, k = -1;
nextval[0] = -1;
while (t[j]) {
if (k == -1 || t[j - 1] == t[k])
if (t[++k] == t[j])
nextval[j++] = nextval[k];
else nextval[j++] = k;
else k = nextval[k];
}
}
int index_kmp(char *s, char *t, int next[]) {//KMP查找函数
int i = 0, j = 0;
while (s[i] && t[j]) {
if (j == -1 || s[i] == t[j]) {
i++; j++;
}
else j = next[j];
}
if (!t[j]) return i - j;
return -1;
}
void replace(char *s, char *b, int position, int lena) {
int i, j, lens = strlen(s), lenb = strlen(b);
if (lenb > lena) {//将a以后的字符串向后挪lenb-lena个位置
for (i = lens + lenb - lena, j =lens; j >= position+lena; i--, j--) s[i] = s[j];
}
else if (lenb < lena) {//将a以后的字符向前挪lenb-lana个位置
for (i = position + lenb, j = position+lena; j <= lens; i++, j++)
s[i] = s[j];
}
i = 0;
while (b[i]) {
s[position++] = b[i++];
}
}
int main() {
char s[40], a[40], b[40], *p;
int next[40], count = 0;
while (1) {
cout <<"Input S:\n"; cin >> s; p = s;
cout <<"Input A:\n"; cin >> a;
get_next(a, next);
while (strlen(p)>=strlen(a)) {//剩余字符串长度小于p时停止查找
int position = index_kmp(p, a, next);
if (position == -1) break;
count++;//count计找到a的次数
if (count == 1) { //找到第一个a时输入b
cout <<"find the first Position:"<< position <<"\nInput B:\n";
cin >> b;
}
replace(p, b, position, strlen(a));
cout << endl<< s << endl;
p += position + strlen(b);//将p定位到position加上a的长度之后,从那之后继续寻找}
if(!count) cout << endl <<"not found:\n"<< s << endl;
else cout <<"\nString a is replaced "<< count <<" times!\n\n";
count = 0;
}
return 0;
}