数据结构与算法基础(王卓)(14):串、数组和广义表(BP、KMP算法)

目录

串的定义(前置条件):

顺序串:(一般常用)

链串:

基本操作:

BF算法:

KMP(算法):


串的定义(前置条件):


顺序串:(一般常用)

//基于线性表的定义所做的更改
#include<iostream>
using namespace std;
#include<stdlib.h>//存放exit
#include<math.h>//OVERFLOW,exit

typedef int Status;
#define MAXLEN 255

struct SString
	//Sequence String
{
	char ch[MAXLEN + 1]; //存储串的一维数组
	int length; //串的当前长度长度
};

链串:

//链串的定义及其基础操作
#include<iostream>
using namespace std;
#include<stdlib.h>//存放exit

#define CHUNKSIZE 80//块的大小可由用户定义
typedef int Status;         //函数调用状态

struct Chunk
    //厚块; 厚片; 大块;  组块;
{
    char ch[CHUNKSIZE];
    Chunk* next;
};

struct LString
{
    Chunk* head, * tail;
    int curlen;//current length:当前长度
};

int main()
{

}

基本操作:

(1) :StrAssign (&T,chars)

串赋值

(2): StrCompare(S,T)

串比较

(3) :Strlength (S)

求串长

(4) :Concat(&T,S1,S2)

串连结

(5): SubString(&Sub,S,pos,len)

求子串

(6): StrCopy(&T,s)

串拷贝

(7) :StrEmpty(S)
//串判空

(8) :ClearString (&S)

清空串


(9) :Index(S,T,pos)

//子串的位置


(11) :Replace(&S,T,V)

串替换


(12) :Strlnsert(&S,pos,T)
//子串插入

(12) :StrDelete(&S,pos,len)

//子串删除


(13) :DestroyString(&S)
//串销毁


BF算法:

brute force:蛮力;暴力;强力

int Index_BF(SString S, SString T, int pos)//暴力算法
{
	int i = pos, 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;
		//模式匹配不成功
	}
}

注解:

(1):

index:序号,编号

(物价和工资等的)指数;指标;索引;标志;

vt.:为…编索引;将…编入索引;

(2):

pos:从位置pos(第pos位)开始(向后)检索

(3):

判断(主串和子串有一个串)检索完了跳出循环的语句不是判断内容是否为空

(实际上电脑系统内部可能随机分配数值,即使我们造了一个该类型的空值也无法实际奏效)

而是:    while (i <= S.length && j <= T.length)


KMP(算法):

next:

#include<iostream>
using namespace std;
#include<stdlib.h>//存放exit
#include<math.h>//OVERFLOW,exit
 
typedef int Status;
#define MAXLEN 255
 
struct SString
	//Sequence String
{
	char ch[MAXLEN + 1]; //存储串的一维数组
	int length; //串的当前长度长度
};
 
void Get_next(SString T, int *next)
//给你一个子串T,教你逐个算出每个位序对应的next[]
{
	int j = 0,//从头开始算起
		k = -1;
	next[0] = -1;//根据公式
	while (j <= T.length - 1)//因为位序从0(而非1)开始
	{
		if (k == -1 || T.ch[k] == T.ch[j])
		{
			j++;
			k++;
			next[j] = k;
		}
		else
			k = next[k];
	}
}
 
int Index_KMP(SString S, SString T, int pos)
{
	int next[MAXLEN];
	Get_next(T, next);
	int i = pos, j = 1;
	while (i <= S.length && j <= T.length)
	{
		if (S.ch[i] == T.ch[j])
		{
			++i; ++j;
		}//主串和子串依次匹配下一个字符
		else
 
			j = next[j];
	}
	if (j > T.length)
		return i - T.length; //匹配成功
	else
		return 0;
}
 
int main()
{
 
}

nextval: 

#include<iostream>
using namespace std;
#include<stdlib.h>//存放exit
#include<math.h>//OVERFLOW,exit

typedef int Status;
#define MAXLEN 255

struct SString
	//Sequence String
{
	char ch[MAXLEN + 1]; //存储串的一维数组
	int length; //串的当前长度长度
};

void Get_nextval(SString T, int nextval[])
//给你一个子串T,教你逐个算出每个位序对应的next[]
{
	int j = 0,//从头开始算起
		k = -1;
	nextval[0] = -1;//根据公式
	while (j <= T.length)
	{
		if (k == -1 || T.ch[k] == T.ch[j])
		{
			j++;
			k++;
			if (T.ch[k] != T.ch[j])
				nextval[j] = k;
			else
				nextval[j] = nextval[k];
		}
		else
			k = nextval[k];
	}
}

int Index_KMP(SString S, SString T, int pos)
{
	int nextval[MAXLEN];
	Get_nextval(T, nextval);
	int i = pos, j = 1;
	while (i <= S.length && j <= T.length)
	{
		if (S.ch[i] == T.ch[j])
		{
			++i; ++j;
		}//主串和子串依次匹配下一个字符
		else
			j = nextval[j];
	}
	if (j > T.length)
		return i - T.length; //匹配成功
	else
		return false;
}

int main()
{

} 

该算法详细研究过程后续将重新整理,详见该系列的15、16:

数据结构与算法基础(王卓)(15):KMP算法详解(含速成套路和详细思路剖析)_宇 -Yu的博客-CSDN博客数据结构与算法基础(王卓)(16):KMP算法详解(代码实现)_宇 -Yu的博客-CSDN博客

猜你喜欢

转载自blog.csdn.net/Zz_zzzzzzz__/article/details/129326355