内容
求一个字符串在另一个字符串中第一次出现的位置,要求:利用键盘输入两个字符串,一个设定为主串,另一个设定为子串,对这两个字符串应该用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) |
程序运行流程图如下:
#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; }