数据结构-串

系列文章目录

第一章 线性表
第二章 栈与队列
第三章 串
第四章 数组与广义表



前言

,即字符串(String),是由零个或多个字符组成的有限序列。一般记为s="a_{1},a_{2},…,a_{n} "
 其中,s是串名,引号(单/双引号都可)括起来的字符序列是串的值;a_{i}可以是字母、数字或其他字符;字符下标从1开始,串中字符的个数n称为串的长度。n=0时的串称为空串(用∅表示)。
子串:串中任意个连续的字符组成的子序列。主串:包含子串的串。
 字符在主串中的位置:字符在串中的序号。(注意位序从1开始,而不是0)
 子串在主串中的位置:子串的第一个字符在主串中的位置。


一、串

1.什么是串

:限定数据元素类型的线性表。
空串:长度为0。
子串:串中任意个连续字符组成的子序列。
两串相等:两串长度相等,对应的每个字符相等。
子串(subString):串中任意几个连续的字符组成的子序列即为该串的子串

主串:相应地,包含该子串的串称为主串

子串的位置(index):子串在主串中首次出现时,该子串的首字符对应在主串中的序号,即为子串在主串中的位置。

这里有一个很经典的例子用来辅助说明。例如,设A和B分别为 A=‘This is a string’ B=‘is’ 则B是A的子串,A为主串。B在A中出现了两次,其中首次出现所对应的主串位置是3。因此,称B在A中的位置为3。 特别地,空串是任意串的子串,任意串是其自身的子串。

连接 (concatenation):连接是一个重要的二进制操作。对于任意两个主串中的子串s和t,它们的连接根据放置s和t 的前后顺序来定符号序列。例如,子串s = love,t = hug,那么st 就是lovehug,ts 就是huglove。

前缀和后缀 prefixes and suffixes:字符串s 可以说是t 的前缀,如果存在一个字符串u 满足条件t =su。如果u 是非空的,那么可以说s 是t 的一个合适的前缀;相应地,串s 可以说t 的后缀如果存在一个串u 满足条件t=us。如果u 是非空的,s 可以说是t 的一个合适的后缀。前缀和后缀可以说是t 的子串。

旋转:串s = uv 可以被说成t 的旋转如果t = vu. 举个例子,当u = 00110, v = 01的时候,串0011001 是0100110 的旋转。

逆转:串的逆转就是具有相同符号单顺序相反的字符串。例如,如果s=abc(a、b和c是字母表中符号),那么s 的逆转就是cba。一个与自身相反的字符串(例如,s=madam,逆转还是madam)被称为回文 palindrome,它还包括空字符串和所有长度为1的字符串。

2.串的基本操作

函数功能
strcpy(p, p1)复制字符串
strncpy(p, p1, n)复制指定长度字符串
strcat(p, p1)附加字符串
strncat(p, p1, n)附加指定长度字符串
strlen(`p)取字符串长度
strcmp(p, p1)比较字符串
strcasecmp(p, p1)忽略大小写比较字符串
strncmp(p, p1, n)比较指定长度字符串
strchr(p, c)在字符串中查找指定字符
strrchr(p, c)在字符串中反向查找
strstr(p, p1)查找字符串

3.串的存储

 静态(定长)顺序结构
Typedef char String[MAXSIZE+1];
 动态(堆分配)顺序结构
typedef struct
{ 
	char *ch;
	int length;
}String;

4.判断字符串是否为空StrEmpty

int StrEmpty(char a[]) {
	if (a[0] == '\0') {
		return -1;
	}
	return 0;
}

5.求字符串长度Str_len

int Str_len(char a[]) {
	int len;
	for ( len = 0; a[len] !='\0';)
	{
		len++
	}
	return len;
}

6.字符串拼接Str_cat

void str_cat(char a[], char b[]) {
	int i,j;
	i = strlen(b);
	for (j = 0; a[j] != '\0'; j++)
	{
		b[j + i] = a[j];
	}
}

7.字符串截取substring

void substring(char a[], int pos, int len, char* c) {
	int i,j=0;
	for ( i = pos; i <pos+len; i++)
	{
		c[j] = a[i];
		j++;
	}
	c[len] = '\0';
}

8.字符串拷贝str_copy

void str_copy(char a[], char b[]) {
	int len = strlen(b);
	for (int i = 0; i < len; ++i) {
		a[i] = b[i];
	}
}

9.字符串替换str_replace

//替换     Replace(&S,T,V)  用V替换主串S中出现的所有与T相等的不重叠的子串

10.字符串插入insert_str

void insert_str(char b[], int pos, char* c) {
	int i,len_b = strlen(b),j=0,len_c = strlen(c);
	int insert_pos = pos; 
	if (pos > len_b) {
		return;
	}
	for (j = 0; j < len_c; j++) {
		for (i = len_b; i >= pos; i--) {
			b[i + 1] = b[i];
		}
		pos++;
		len_b++;
	}
	//puts(b);
	for (i = insert_pos, j = 0; i < insert_pos + len_c; i++) {
		b[i] = c[j];
		j++;
	}
}

10.字符串删除delete_str

//StrDelete(&S,pos,len)  从串S中删除第pos个字符起长度为len的子串

11.字符串释放DestroyString

//释放     DestroyString(&S)

二、字串串匹配算法

1.kmp

在这里插入图片描述

代码如下(示例):

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int kmp(char a[], char b[], int next[]);
int get_next(char b[], int next[]);
int main() {
	char a[20] = "aaaadascaafgh";
	char b[10] = "adascaa";
	int next[] = { -1,0,0,1,0,0,1 };
	int c = kmp(a, b, next);
	if (c >= 0) {
		printf("匹配成功,在第%d个位置匹配成功\n", c + 1);
	}
	else {
		printf("匹配失败\n");
	}
	
	int next1[7];
	get_next(b, next1);
	for(int i = 0; i <= 6; i++) {
		printf("%d \n", next[i]);
	}
}
int get_next(char b[], int next[]) {
	int i = 0, j = -1;
	int m = strlen(b);
	next[0] = -1;
	while (i <= m - 2) {
		if (j == -1 || b[i] == b[j]) {
			next[i + 1] = j + 1;
			++i;
			++j;
		}
		else {
			j = next[j];
		}
	}
}
int kmp(char a[], char b[], int next[]) {
	int i=0, j=0;
	int m = strlen(a),n=strlen(b);
	while (i <= m-1 && j <= n-1)
	{
		if ( j == -1 || a[i] == b[j]) {
			i++;
			j++;
		}
		else {
			j = next[j];
		}
	}
	if (j >= n ) {
		return i - n;
	}
	else {
		return -1;
	}
}

2.求next[]数组

在这里插入图片描述

代码如下(示例):(期末考试不要求掌握,但得会手写next数组)

int get_next(char b[], int next[]) {
	int i = 0, j = -1;
	int m = strlen(b);
	next[0] = -1;
	while (i <= m - 2) {
		if (j == -1 || b[i] == b[j]) {
			next[i + 1] = j + 1;
			++i;
			++j;
		}
		else {
			j = next[j];
		}
	}
}

2.BF

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
void main() {
	char s[] = "abceeffqq88w";
	char t[] = "fqq8";
	int pos, index;
	printf("请输入您要查找子串的起始位置\n");
	scanf("%d", &pos);
	index = BF(s, t, pos);
	printf("%s在%s中的起始位置为:%d\n", t, s, index);
}
int BF(char s[], char t[], int pos) {
	int i, j;
	if (pos<0 || pos>strlen(s)) {
		printf("pos error !\n");
		return;
	}
	i = pos; j=0;
	while (t[j]!='\0' && s[i] != '\0') {
		if (s[i] == t[j]) {
			i++; j++;
		}else {
			i = i - j + 1;
			j = 0;
		}
	}
	if (t[j] == '\0') {
		return i - strlen(t);
	}else {
		return -1;
	}
}

总结

只是写了部分基础的东西为了考试做得笔记

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

是阿鹏啊~

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

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

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

打赏作者

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

抵扣说明:

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

余额充值