串,匹配算法

串(string):零个或多个任意字符组成的有限序列

s:"a1a2a3……an"

串名 串值 串长

子串:一个串中任意个连续字符组成的子序列

主串:包含子串的串

字符位置:字符在序列中的序号为该字符在串中的位置

子串位置:子串第一个字符在主串中的位置

空格串:由一个或多个空格组成的串

空串:不包含任何字符

串相等:当且仅当两个串的长度相等并且各个对应位置上的字符都相同时,才是相等的

所有的空串是相等的

基本操作:


StrAssign(&T, chars)//串赋值
StrCompare(S, T)//串比较
StrLength(S)//求串长
Concat(&T, s1, s2)//串连结
SubString(&Sub, S, pos, len)//求子串
StrCopy(&T, s)//串拷贝
StrEmpty(S)//串判空
ClearStr(S)//清空串
Index(S, T, pos)//子串的位置
Replace(&S, t, v)//串替换
StrInsert(&S, pos, T)//子串插入
StrDelete(&S,pos,len)//子串删除
DestroyStr(&S)//串销毁

串的顺序存储结构

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include<stdlib.h>
#include<string.h>
#define MAXSIZE 255
typedef int status;
typedef struct {
	char ch[MAXSIZE + 1];
	int length;

}SString;

#define CHUNKSIZE 80
typedef struct Chunk {
	char ch[CHUNKSIZE];
	struct Chunk* next;
}Chunk;

typedef struct {
	Chunk* head, * tail;
	int curlen;
}LString;

链式存储


#define CHUNKSIZE 80
typedef struct Chunk {
	char ch[CHUNKSIZE];
	struct Chunk* next;
}Chunk;

typedef struct {
	Chunk* head, * tail;
	int curlen;
}LString;



串的模式匹配算法

确定主串中所含子串(模式串)第一次出现的位置(定位)

算法种类:BF算法,KMP算法

BF:Brute-Force暴力算法,亦称简单匹配算法。采用穷举法的思路。

主串s:aaaabcd

子串t:abc

s的每一个字符开始依次比较

s长度n=6,t长度m=4

Index(S,T,pos);

将主串的第pos个字符和模式串的第一个字符比较

int Index_BF(SString S, SString T ,int pos) {
	int i = pos;
	int j = 1;
	while (i<=S.length&&j<=T.length)
	{
		if (S.ch[i]==T.ch[j])//主串和子串依次匹配下一个字符
		{
			++i;
			++j;
		}
		else//主串、子串指针回溯重新开始下一次匹配
		{
			i = (i - j+1)+1 ;
			j = 1;
		}
	}
	if (j>=T.length)
	{
		return i - T.length;
	}
	else
	{
		return 0;
	}
}



最好情况:O(m)

最差情况:O(n*m)

平均:O(n*m)

平均效率较差

改进为KMP后提高到O(n+m)


KMP算法:


int next[100] = { 0 };
void get_next(SString T, int next[]) {
	int i = 1;
	next[1] = 0;
	int j = 0;
	while (i<T.length)
	{
		if (j==0||T.ch[i]==T.ch[j])
		{
			++i; ++j;
			next[i] = j;
		}
		else
		{
			j = next[j];
		}
	}
}

int Index_KMP(SString S, SString T, int pos) {
	int i = pos;
	int j = 1;
	while (i <= S.length && j <= T.length)
	{
		if (j==0||S.ch[i] == T.ch[j])//主串和子串依次匹配下一个字符
		{
			++i;
			++j;
		}
		else//主串、子串指针回溯重新开始下一次匹配
		{
			j = next[j];//i不变,j后退
		}
	}
	if (j >= T.length)
	{
		return i - T.length;
	}
	else
	{
		return 0;
	}
}


求nextval数组:

int nextval[100] = { 0 };
void get_nextval(SString T, int nextval[]) {
	int i = 1;
	nextval[1] = 0;
	int j = 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];
		}
	}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

湿物男

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值