数据结构实验报告4
学号:20xxxxxxxx 姓名:xxx 专业:计算机科学与技术/软件工程
知识范畴:串 完成日期:20xx年 xx月 xx日
实验题目:基于KMP算法的子串查找与替换
课程目标1(60%) | 课程目标2(40%) | 得分(100分) 期末成绩占比5% | 批阅人签字 |
程序代码及测试 | 写作、排版、代码注释等 | ||
实验内容及要求:从键盘输入主串s以及子串t1和t2。编写程序,将主串s中所有t1子串替换为t2子串,输出替换后得到的串以及t1被替换的次数。要求子串查找采用KMP算法。
实验目的:掌握KMP算法。
数据结构设计简要描述:结构体内有一个char数组和一个int变量存储串的长度
算法设计简要描述:计算模式串的next函数值,为主串匹配模式串的时候提供平移的距离,减少匹配的次数,优化了算法的时间复杂度
输入/输出设计简要描述:输入为主串,字串1,字串2,输出为替换后的主串
编程语言说明:C++
主要函数说明:
在初始化串的时候,在串的末尾补上‘\0’,避免字符串存取时出错
程序测试结果:
源程序代码:
#include <iostream>
#include <string>
#include <cstring>
#define MAXSIZE 255
using namespace std;
bool fact;
typedef struct
{
char ch[MAXSIZE];
int length;
}SString;
void InitString(SString &s)
{
cin >> s.ch;
s.length = strlen(s.ch);
s.ch[s.length] = '\0';
}
int* Get_next(SString T)
{
int* next = new int[MAXSIZE];
next[0] = -1;
int i = 0;
int j = -1;
while (i<T.length-1)
{
if ((j == -1) || (T.ch[i] == T.ch[j]))
{
i++;
j++;
next[i] = j;
//cout << next[i] << endl;
}
else
{
j = next[j];
}
}
return next;
}
int KMP(SString S, SString T1)
{
//cout << "kmp" << endl;
int i=0, j=0;
int* next =Get_next(T1);
while (i <S.length && (j < T1.length||j==-1))
{
if (j == -1 || S.ch[i] == T1.ch[j]) { i++; j++; } /*继续比较后继字符*/
else { j = next[j]; /*模式串向右移动*/ }
}
if (j >= T1.length)return i - j; /*返回子串所在位置*/
else return -1; /*没有找到,返回-1*/
}
SString ChangeString(SString S, SString T1, SString T2,int pos)
{
//cout << "change" << endl;
int i=0, j=0, k=0;
char temp[MAXSIZE];
for (k = 0; k < S.length; k++)
{
temp[k] = S.ch[k];
}
temp[S.length] = '\0';
S.length = S.length - T1.length + T2.length;
for (i = pos; i < S.length; i++)
{
S.ch[i + T2.length] = temp[i + T1.length];
}
for (i = pos; j < T2.length; i++)
{
S.ch[i] = T2.ch[j];
j++;
}
return S;
}
int main()
{
int pos=0;
SString S, T1, T2;
cout << "请输入主串" << endl;
InitString(S);
cout << "请输入被替换的字串" << endl;
InitString(T1);
cout << "请输入要换入的字串" << endl;
InitString(T2);
pos = KMP(S, T1);
int* next = new int[MAXSIZE];
next=Get_next(T1);
cout << "next函数值为" << endl;
for (int k = 0; k < T1.length; k++)cout << next[k] << endl;;
int counter = 0;
while (pos != -1)
{
S=ChangeString(S, T1, T2, pos);
counter++;
pos = KMP(S, T1);
}
cout <<"替换后的串为" << S.ch <<endl<<"字串被替换" <<counter<<"次" << endl;
return 0;
}
/*测试案例1
aacatcataa
cat
dog
*/
/*测试案例2
aacatcataa
cat
fish
*/