数据结构:串(BF,KMP算法)和广义表

串是零个或多个字符组成的有限序列。串中所包含的字符个数为该串的长度。串中任意个连续的字符组成的子序列称为该串的子串。包含子串的相应地称为主串。通常,把子串在主串中第一次出现时,子串的第一次字符在主串中的序号,定义为子串在主串中的序号。


建立

#include<stdio.h>
#define SIZE 100
typedef struct
{
	char data[SIZE];
	int len;
} String;

结构体中包含一个字符串数组和串长。

初始化

void Init(String &s)
{s.len=0;}

令串长为0。

基本操作

1.入串

void Input(String &s,char *ps)
{
	while(*ps)
	{
		s.data[++s.len]=*ps;
		ps++;
	}
}

参数中定义了一个指针,指针刚开始指向定义的字符数组中第一个元素,依次赋值给
结构体中的数组,再完成指针的移动。
注意此时的++s.len 使该字符串有了一个头结点不存放任何值。

2.遍历

void Display(String s)
{
	for(int i=1;i<=s.len;i++)
		putchar(s.data[i]);
}

从首结点开始遍历串中的元素。

判断串相等处的下标

1.BF算法

int BF(String s,String t){
	int i=1;
	int j=1;
	while(i<=s.len&&j<=t.len)
		if(s.data[i]==t.data[j]){
			i++;
			j++;
		} 
		else{
			i=i-j+2;
			j=1;
		}
	if(j>t.len)
		return i-j+1;
	return -1;
}

此算法为暴力算法,定义的两个指针每次匹配都需返回。
两个字符串均从头开始匹配,若值相等则指针后移,否则j回到初始位置,i回到i-j+2的位置。直到j超过该字符串的长度,证明串匹配成功,此时i-j+1的位置就是串相等处的下标。
否则匹配失败返回-1。

在这里插入图片描述

2.KMP算法

void GetNext(String s,int *next){
	int i=1,j=0;
	next[1]=0;
	while(i<=s.len){
		if(j==0||s.data[i]==s.data[j]){
			i++;
			j++;
			next[i]=j;
		}
		else j=next[j];
	}
}
int KMP(String s,String t){
	int i=1;
	int j=1;
	int next[SIZE];
	GetNext(t,next);
	while(i<=s.len&&j<=t.len)
		if(j==0||s.data[i]==t.data[j]){
			i++;
			j++;
		} 
		else
			j=next[j];
	if(j>t.len)
		return i-j+1;
	return -1;
}

此算法不需要对主串中的i值进行返回,只通过对j指针的返回完成串的匹配。
首先对要判断的字串进行next求值,再返回所求的下标。

在这里插入图片描述

代码测试

int main(){
	char ch1[]="20200305016",ch2[]="0030";
	String s,t;
	Init(s);Init(t);
	Input(s,ch1);Input(t,ch2);
	Display(s);printf("\n");	
	Display(t);printf("\n");
	printf("%d,%d",BF(s,t),KMP(s,t));
	return 0; 
	
}

在这里插入图片描述


广义表

线性表是一种特殊的广义表,但广义表不一定是线性表。


广义表中的基本操作

在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

头马上秃

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

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

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

打赏作者

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

抵扣说明:

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

余额充值