实现的功能
bool StrAssign(SString& S, char c); //赋值操作
void StrCopy(SString& T, SString S); //复制串
bool StrEmpty(SString S); //判空
bool Concat(SString& T, SString S1, SString S2); //串连接
int StrLength(SString S); //求串长
bool SubString(SString& Sub, SString S, int pos, int len); //求子串
int StrCompare(SString S, SString T); //比较字符串大小
int Index(SString S, SString T); //求子串的位置
int Index_Simple(SString S, SString T); //朴素模式匹配算法
void get_next(SString T, int next[]); //获取next数组
void get_nextval(SString T, int nextval[]); //获取nextval数组
int Index_KMP_Next(SString S, SString T); //KMP算法使用next数组
int Index_KMP_Nextval(SString S, SString T); //KMP算法使用next数组
void CleanString(SString& S); //清空链表
//void DystroyString(SString& S); //销毁串 数组形式,系统自动收回
void ShowString(SString S); //输出串
完整代码:
/*
Name:SString(串的顺序实现)
Copyright:
Author: Sdjzu_Nxy
Date: 2023 年 2 月 28 日
Description:
*/
#include<stdio.h>
#include<stdlib.h>
#define MaxSize 255
typedef struct {
char ch[MaxSize];
int length;
} SString;
bool StrAssign(SString& S, char c); //赋值操作
void StrCopy(SString& T, SString S); //复制串
bool StrEmpty(SString S); //判空
bool Concat(SString& T, SString S1, SString S2); //串连接
int StrLength(SString S); //求串长
bool SubString(SString& Sub, SString S, int pos, int len); //求子串
int StrCompare(SString S, SString T); //比较字符串大小
int Index(SString S, SString T); //求子串的位置
int Index_Simple(SString S, SString T); //朴素模式匹配算法
void get_next(SString T, int next[]); //获取next数组
void get_nextval(SString T, int nextval[]); //获取nextval数组
int Index_KMP_Next(SString S, SString T); //KMP算法使用next数组
int Index_KMP_Nextval(SString S, SString T); //KMP算法使用next数组
void CleanString(SString& S); //清空链表
//void DystroyString(SString& S); //销毁串 数组形式,系统自动收回
void ShowString(SString S); //输出串
bool StrAssign(SString& S, char c)
{
if (S.length == MaxSize) {
return false;
}
S.ch[S.length + 1] = c;
S.length++;
return true;
}
void StrCopy(SString& T, SString S)
{
for (int i = 1; i <= S.length; i++) {
T.ch[i] = S.ch[i];
}
T.length = S.length;
}
bool StrEmpty(SString S)
{
return S.length == 0;
}
bool Concat(SString& T, SString S1, SString S2)
{
if (S1.length + S2.length >= MaxSize) {
return false;
}
StrCopy(T, S1);
for (int i = 1; i <= S2.length; i++)
{
StrAssign(T, S2.ch[i]);
}
return true;
}
int StrLength(SString S)
{
return S.length;
}
bool SubString(SString& Sub, SString S, int pos, int len)
{
if (pos + len - 1 > S.length) {
return false;
}
for (int i = pos; i < pos + len; i++) {
Sub.ch[i - pos + 1] = S.ch[i];
}
Sub.length = len;
return true;
}
int StrCompare(SString S, SString T)
{
for (int i = 0; i <= S.length && i <= T.length; i++) {
if (S.ch[i] != T.ch[i]) {
return S.ch[i] - T.ch[i];
}
}
return S.length - T.length;
}
int Index(SString S, SString T)
{
int i = 1, n = StrLength(S), m = StrLength(T);
SString sub;
while (i <= n - m + 1) {
SubString(sub, S, i, m);
if (StrCompare(sub, T) != 0) {
i++;
}
else
{
return i;
}
}
return 0;
}
int Index_Simple(SString S, SString T)
{
int i = 1, j = 1;
while (i <= S.length && j <= T.length) {
if (S.ch[i] == T.ch[j]) {
i++, j++;
}
else {
i = i - j + 2;
j = 1;
}
}
if (j > T.length) {
return i - T.length;
}
else
{
return 0;
}
}
int Index_KMP_Next(SString S, SString T)
{
int* next = new int[T.length + 1];
get_next(T, next);
printf("The next is:\n");
for (int k = 1; k <= T.length; k++) {
printf("%d ",next[k]);
}
printf("\n");
int i = 1, j = 1;
while (i <= S.length && j <= T.length)
{
if (j == 0 || S.ch[i] == T.ch[j])
{
i++;
j++;
}
else
{
j = next[j];
}
}
if (j > T.length) {
return i - T.length;
}
else
{
return 0;
}
delete[]next;
next = NULL;
}
int Index_KMP_Nextval(SString S, SString T)
{
int* nextval = new int[T.length + 1];
get_next(T, nextval);
printf("The nextval is:\n");
for (int k = 1; k <= T.length; k++) {
printf("%d ", nextval[k]);
}
printf("\n");
int i = 1, j = 1;
while (i <= S.length && j <= T.length)
{
if (j == 0 || S.ch[i] == T.ch[j])
{
i++;
j++;
}
else
{
j = nextval[j];
}
}
if (j > T.length) {
return i - T.length;
}
else
{
return 0;
}
delete[]nextval;
nextval = NULL;
}
void get_next(SString T, int next[])
{
int i = 1, j = 0;
next[1] = 0;
while (i < T.length)
{
if (j == 0 || T.ch[i] == T.ch[j]) {
/*i++;
j++;
next[i] = j;*/
next[++i] = ++j;
}
else
{
j = next[j];
}
}
}
void get_nextval(SString T, int nextval[])
{
int i = 1, j = 0;
nextval[1] = 0;
while (i < T.length) {
if (j == 0 || T.ch[i] == T.ch[j]) {
i++;
j++;
if (T.ch[i] != T.ch[j]) {
nextval[i] = j;
}
else {
nextval[i] = nextval[j];
}
}
else {
j = nextval[j];
}
}
}
void CleanString(SString& S)
{
for (int i = 1; i <= S.length; i++) {
S.ch[i] = NULL;
}
S.length = 0;
}
void ShowString(SString S)
{
for (int i = 1; i <= S.length; i++) {
printf("%c", S.ch[i]);
}
printf("\n");
}
int main() {
SString S;
S.length = 0;
printf("The String is empty? %d\n", StrEmpty(S));
if (!StrAssign(S, 'a'))
{
printf("Str Assign is error!\n");
}
if (!StrAssign(S, 'b'))
{
printf("Str Assign is error!\n");
}
if (!StrAssign(S, 'c'))
{
printf("Str Assign is error!\n");
}
if (!StrAssign(S, 'n'))
{
printf("Str Assign is error!\n");
}
if (!StrAssign(S, 'x'))
{
printf("Str Assign is error!\n");
}
if (!StrAssign(S, 'y'))
{
printf("Str Assign is error!\n");
}
printf("The String is empty? %d\n", StrEmpty(S));
printf("The String length is %d\n", StrLength(S));
SString T;
T.length = 0;
printf("The String is empty? %d\n", StrEmpty(T));
StrCopy(T, S);
printf("The String is empty? %d\n", StrEmpty(T));
printf("The String length is %d\n", StrLength(T));
SString St;
St.length = 0;
if (!Concat(St, S, T)) {
printf("The St length is small!\n");
}
printf("The String is empty? %d\n", StrEmpty(St));
printf("The String length is %d\n", StrLength(St));
ShowString(S);
ShowString(T);
ShowString(St);
int flag = StrCompare(S, T);
//int flag = StrCompare(S, St);
//int flag = StrCompare(St, T);
if (flag > 0) {
printf("The result is S > T\n");
}
else if (flag == 0){
printf("The result is S = T\n");
}
else
{
printf("The result is S < T\n");
}
SString Sub;
Sub.length = 0;
SubString(Sub, St, 4, 3);
ShowString(Sub);
printf("The sub's pos is %d\n", Index(S, Sub));
CleanString(S);
ShowString(S);
printf("The S is empty? %d\n", StrEmpty(S));
printf("The String length is %d\n", StrLength(S));
printf("The sub's pos is %d\n", Index_Simple(St, Sub));
SString a;
a.length = 0;
if (!StrAssign(a, '1'))
{
printf("Str Assign is error!\n");
}
if (!StrAssign(a, '2'))
{
printf("Str Assign is error!\n");
}
ShowString(a);
printf("The a's pos is %d\n", Index_Simple(St, a));
/*use next[]*/
if (Index_KMP_Next(St, Sub) == 0) {
printf("The sub is not in the St!");
}
else
{
ShowString(St);
ShowString(Sub);
printf("The Sub's pos is %d\n", Index_KMP_Next(St, Sub));
}
if (Index_KMP_Next(St, a) == 0) {
printf("The a is not in the St!");
}
else
{
ShowString(St);
ShowString(a);
printf("The a's pos is %d\n", Index_KMP_Next(St, a));
}
/*use nextval[]*/
if (Index_KMP_Nextval(St, Sub) == 0) {
printf("The sub is not in the St!");
}
else
{
ShowString(St);
ShowString(Sub);
printf("The Sub's pos is %d\n", Index_KMP_Nextval(St, Sub));
}
if (Index_KMP_Nextval(St, a) == 0) {
printf("The a is not in the St!");
}
else
{
ShowString(St);
ShowString(a);
printf("The a's pos is %d\n", Index_KMP_Nextval(St, a));
}
}
运行结果:
总结
模式匹配算法比较晦涩,建议先进行理论学习,弄懂算法原理,会求next数组,nextval数组,然后在进行代码复现。可以通过视频讲解学习,这样有助于理解,比较直观。