【数据结构】字符串的基本操作

1.字符串的结构体

#include<iostream>
using namespace std;

//注意:本代码使用的字符串结构是字符数组是舍弃ch[0]的位置不用,并且用一个专门的变量来存储字符串长度!
#define MAXLEN 255
typedef struct {
	char ch[MAXLEN];
	int length;
}SString;

2.字符串的基本操作

1.字符串的长度

int StrLength(SString s) {
	return s.length;
}

2.获取主串中的子串

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];//因为串字符数组的0下标不存储数据
	}
	Sub.length = len;
	return true;
}

3.字符串的比较

int StrCompate(SString S, SString T) {
	for (int i = 1; i <= S.length && i <= T.length; i++) {
		if (S.ch[i] != T.ch[i]) {
			return S.ch[i] - T.ch[i];//如果字符串S和T的对应位数值不一样,返回两字符串对应位比较的数值
		}
	}
	return S.length - T.length;//如果字符串S和T的对应位数值一样,比较两字符串长度,并返回
}

3.字符串匹配算法

1.使用基本函数操作实现朴素模式匹配算法

int index(SString S, SString T) {//使用基本函数操作实现朴素模式匹配算法
	int i = 1;//用于遍历主串
	int n = StrLength(S);
	int m = StrLength(T);
	SString sub;//用于暂存子串
	while (i <= n - m - 1) {//循环的临界条件:i定位在主串的位置截下来的子串长度已不足目标子串的长度m
		SubString(sub, S, i, m);
		if (StrCompate(sub, T) == 0) {
			return i;
		}
		else {
			i++;
		}
	}
	return 0;
}

 2.不使用基本函数操作实现朴素模式匹配算法

int Index(SString S, SString T) {//不使用基本函数操作实现朴素模式匹配算法,最坏时间复杂度=O(nm)
	int i = 1;//定位主串
	int j = 1;//定位模式串
	while (i <= S.length && j <= T.length) {/*临界条件
											  1.i>S.length && j <= T.length 表示没有找到模式串
											  2.i>S.length && j > T.length 表示找到了模式串*/
		if (S.ch[i] == T.ch[j]) {
			i++;
			j++;
		}
		else {
			j = 1;
			i = i - j + 2;/*i是主串中的定位
						    j是模式串中的定位,但也代表主串中每次要比对的子串中的第j个字符
						    i-j+1代表要回到该次要比较的子串的头部
							则i-j+2代表要回到该次要比较的子串的下一个位置,即开始了新一轮的子串比对*/
		}
	}
	if (j > T.length) {
		return i - j + 1; //找到了模式串
		//return i-T.length;
	}
	else {
		return 0;//没有找到模式串
	}
}

3.KMP算法

/*总括: 字符匹配时,i++,j++
        字符(非模式串第一位)不匹配时,j变换位置(变换位置由next数组决定)
		字符(模式串第一位)不匹配时,i++,j++*/
int Index_KMP(SString S, SString T, int next[]) {/*next[]数组的内容由模式串来决定
												   但next数组的0下标都不存储数据,且1下标存储的数据为0*/
	int i = 1, j = 1;
	while (i <= S.length && j <= T.length) {
		if (j == 0 || S.ch[i] == T.ch[j]) {/*此处if判断显示i的移动由两种情况引起:
											 1.主串跟模式串的字符匹配
											 2.模式串的第一位的字符与主串字符不匹配
											 因算法中i++与j++是一体的,故将next数组1下标存储的数据置为0
											 这样两种情况中都可以同时使i++与j++*/
			i++;
			j++;
		}
		else {
			j = next[j];/*模式串的字符与next数组的数字一一对应
						  若第一位字符不匹配时,j=0,使i++*/
		}
	}
	if (j > T.length) {
		return i - T.length;
	}
	else {
		return 0;
	}
}

  • 10
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值