/*程序说明:
* 程序是由顺序表实现,功能为查找两字符串中的最长公共子串;
* 两条字符串分别由两个顺序表存储;
* 查找思路是分解出短的那条字符串的全部连续子串(例如abc分解为abc,ab,a,bc,b,c),
* 再使用kmp算法将该全部子串与长的那条字符串进行匹配,找到最长的那条子串;
* 完成日期:2017.5.20
* 编译环境:visual studio 2015
*/
#include<iostream>
using namespace std;
const int MaxNum = 100;
struct SeqString//顺序表结构
{
int length;//长度
char c[MaxNum];//存储数据
};
typedef struct SeqString* PSeqString;
PSeqString creatString();
void find(PSeqString t, PSeqString p);
int KMPmatch(PSeqString t, PSeqString p2, int* next);
void makenext(PSeqString p, int* next);
void display(PSeqString pstr);
int main()
{
PSeqString p = new SeqString;
p = creatString();
PSeqString t = new SeqString;
t = creatString();
find(p, t);
cin.get(); cin.get();//暂停
}
PSeqString creatString()//创建并初始化一条字符串
{
PSeqString pstr = new SeqString;
cout << "输入其中一个字符串:\n";
cin >> pstr->c;
pstr->length = strlen(pstr->c);
return pstr;
}
void find(PSeqString t, PSeqString p)//查找公共子串
{
PSeqString temp = new SeqString;
if (t->length < p->length)//交换使得p串为更短的那个字符串
{
temp = t;
t = p;
p = temp;
}
int* next = new int[MaxNum];//next数组
int len = 0, maxlen = 0, loc = 0;//len为子串长度,maxlen为匹配成功的最长子串长度,loc为开始匹配子串的首下标
PSeqString p2 = new SeqString;
int i, k, l; //i,j,k都是是字符串的下标
//利用循环取不同的i和len,以达到取p不同的子字符串的目的
for (int i = 0; i < p->length; i++)//改变i,此处i是p字符串的下标
{
for (len = p->length - i; len > 0; len--)//改变len
{
p2->length = len;
for (k = 0, l = i; k < len; k++, l++)//使得p2为即将进行匹配的子串
{
p2->c[k] = p->c[l];
}
makenext(p2, next);//获取p2的next数组
if (KMPmatch(t, p2, next) && len > maxlen)//子串匹配成功且len最大则保存len与i
{
maxlen = len;
loc = i;
}
}
}
p2->length = maxlen;
for (k = 0, l = loc; k < maxlen; k++, l++)//使得p2为最长公共子串
{
p2->c[k] = p->c[l];
}
cout << "最长的公共子串为: ";
display(p2);
delete(p2);
delete(temp);
}
int KMPmatch(PSeqString t, PSeqString p2, int* next)//kmp算法字符串匹配
{
int i = 0, j = 0;
while (i < p2->length&&j < t->length)
{
if (i == -1 || p2->c[i] == t->c[j])
{
i++, j++;
}
else
i = next[i];
}
if (i >= p2->length)
return 1;
else
return 0;
}
void makenext(PSeqString p, int* next)//kmp算法求next数组
{
int i = 0, k = -1;
next[0] = -1;
while (i < p->length - 1)
{
while (k >= 0 && p->c[i] != p->c[k])
k = next[k];
i++, k++;
if (p->c[i] == p->c[k])
next[i] = next[k];
else
next[i] = k;
}
}
void display(PSeqString pstr)//显示pstr顺序表中的数据
{
for (int i = 0; i < pstr->length; i++)
{
cout << pstr->c[i];
}
}
利用KMP算法,求顺序表存储的两个字符串的最长公共子串
最新推荐文章于 2022-09-11 00:33:05 发布
本文详细介绍了如何运用KMP算法来寻找顺序表存储的两个字符串之间的最长公共子串。通过深入解析KMP算法的原理,结合C++编程,展示了一种高效解决此类问题的方法。
摘要由CSDN通过智能技术生成