求一个字符串在另一个字符串中第一次出现的位置,要求:利用键盘输入两个字符串,一个设定为主串,另一个设定为子串,对这两个字符串应该用KMP算法,求出子串在主串中第一次出现的位置。

内容

        求一个字符串在另一个字符串中第一次出现的位置,要求:利用键盘输入两个字符串,一个设定为主串,另一个设定为子串,对这两个字符串应该用KMP算法,求出子串在主串中第一次出现的位置。

算法分析

        本题要完成KMP算法的实现,主要就是要使用串的存储结构来完成。首先要定义一个函数GetNext()用来求next的值,然后求模式串t的next函数值并且存放到数组next当中,函数IndexKmp()用来实现模式匹配算法。就是子串中的每一个字符依次和主串中的一个连续的字符序列相等,则成为匹配成功,反之则是匹配不成功,函数中Get Next()是求出模板串t的next函数值并且存入到数组next中,函数IndexKmp()为模式匹配函数,是用来模式串的next函数求t在主串s中第pos个字符之前的位置。当某个匹配位置不成功时,应该从字串的下一个位置开始新的比较。将这个位置的值存放到next数组当中,其中next数组的元素满足next[j]=k,表示当子串中的第j+1个字符发生匹配不成功的情况下,应该从子串的第k+1个字符开始新的匹配。

概要设计

KMP算法的实现

函数

void GetNext(DataType* t, int* next, int tlength)

int IndexKmp(DataType* s, DataType* t, int pos, int tlength, int slength, int* next)

程序运行流程图如下:

求一个字符串在另一个字符串中第一次出现的位置,要求:利用键盘输入两个字符串,一个设定为主串,另一个设定为子串,对这两个字符串应该用KMP算法,求出子串在主串中第一次出现的位置。

 

 

#include <stdio.h>
#include<string.h>
#define MAXNUM 100
typedef char DataType;
typedef struct {
	DataType data[MAXNUM];
	int len;
}SString;
void GetNext(DataType* t, int* next, int tlength)//求模式串t的next函数值并存入数组next当中
{
	int i = 1, j = 0;
	next[1] = 0;
	while (i < tlength)
	{
		if (j == 0 || t[i] == t[j])
		{
			++i;
			++j;
			next[i] = j;
		}
		else
			j = next[j];
	}
}
int IndexKmp(DataType* s, DataType* t, int pos, int tlength, int slength, int* next)//利用模式串的t的next函数求t在主串s中第pos个字符后面的位置
{
	int i = pos, j = 1;
	while (i <= slength && j <= tlength)
	{
		if (j == 0 || s[i] == t[j])//两个字符相同的情况,或者模式串j第一个字符进行比较时
		{
			++i;
			++j;
		}
		else
			j = next[j];
	}
	if (j > tlength)
		return i - tlength;
	else
		return 0;
}
int main()
{
	int locate, tlength, slength, next[256];
	DataType s[256], t[256];
	printf("请输入第一个串(母串):");
	scanf_s("%s",s,256);
	slength = strlen(s);
	printf("请输入第二个字符串(子串):");
	scanf_s("%s", t, 256);
	tlength = strlen(t);
	GetNext(t, next, tlength);
	locate = IndexKmp(s, t, 0, tlength, slength, next);
	printf("位置匹配:%d\n",locate);
	return 0;
}

上一篇:数据结构C语言—线性表【顺序存储】顺序表(定义结构体变量实现)


下一篇:数据结构--不设头指针的循环链队列