数据结构-串

server/2025/1/11 18:46:41/

串的实现

在C语言中所使用的字符串就是串的数据类型的一种。

串的存储结构
定长顺序存储表示

类似于线性表的顺序存储结构,用一组连续的存储单元存储串值的字符序列。

#define MAXLEN 255 //预定义最大串长为255
​
typedef struct SString
{char ch[MAXLEN]; //每个分量存储一个字符int length;   //串的实际长度
}SString;

串的实际长度只能小于或等于MAXLEN,超过预定义长度的串值会被社区,称为截断。串长的表示由两种方法:一种是通过length存放串的长度;二是在串值后面加一个不计入串长的结束标记字符'\0'(C语言种字符串就是采用这种方法),此时串就根据'\0'来算长度。

堆分配存储表示

堆分配存储表示仍然以一组地址连续的存储单元存放串,但存储空间是动态分配获得。

typedef struct{char *ch;   //按串长分配存储区,ch指向串的首地址int length; //串的长度
}HString;

在C语言中,用malloc()为每个新产生的串分配一块串长所需的存储空间。

块链存储表示

类似于链式存储结构,也可采用链式方式存储串值。

//串的结点
typedef struct StringNode{char ch[4];  //每个结点存多个字符 提高存储密度struct StringNode* next; //指向下一个结点
};

串的基本操作
赋值操作
bool StrAssign(SString *T, char chars[])
{//获取要赋值字符串长度int charsLen = strlen(chars);
​// 长度为零表示空字符串,退出循环if (!charsLen)return false;for (size_t i = 0; i < charsLen; i++){T->ch[i] = chars[i];}
​T->length = charsLen;return true;
}

复制操作
bool StrCopy(SString *T, const SString S)
{if (!S.length)return false;
​for (size_t i = 0; i < S.length; i++){T->ch[i] = S.ch[i];}
​// 若要赋值的长度大于原先字符串长度就增长if (S.length > T->length){T->length = S.length;}
​return true;
}

判空操作
bool StrEmpty(const SString *S)
{return S->length == 0;
}

比较操作
int StrCompare(const SString S, const SString T)
{int i = 0;while (i != S.length || i != T.length){if (S.ch[i] == T.ch[i]){i++;}else{//若S>T 返回大于0的数 若S<T 返回小于0的数return S.ch[i] - T.ch[i];}}//若结束循环没有比较出结果说明必有一个长度要更长return S.length - T.length;
​
}

求子串
// 求字串 Sub来返回串S的第pos个字符起长度为len的字串
bool SubString(SString *Sub, SString S, char pos, int len)
{if (S.length == 0)return false;int index = 0;for (size_t i = 0; i < S.length; i++){if (S.ch[i] == pos){// 记录pos字符在S中的起始位置index = i;break;}}// 判断len是否要长于S字符串中pos开始后的长度if (len > S.length - index)return false;for (size_t i = 0; i < len; i++){Sub->ch[i] = S.ch[index];index++;Sub->length++;}return true;
}

串联结
// 用T返回由S1和S2拼接而成的新串,S2拼接在S1前
bool Concat(SString *T, SString S1, SString S2)
{for (size_t i = 0; i < S1.length; i++){T->ch[i] = S1.ch[i];T->length++;}int index = 0;for (size_t i = S1.length; i < S1.length + S2.length; i++){T->ch[i] = S2.ch[index];index++;T->length++;}
​return true;
}

定位操作(简单的模式匹配算法
// 定位操作 若主串S中存在与串T值相同的字串,则返回它在S中第一次出现的位置,否则为0
int Index(SString S, SString T)
{// i和j分别为S和T的计数指针int i = 0, j = 0;if (S.length == 0 || T.length == 0)return i;while (i < S.length && j < T.length){if (S.ch[i] == T.ch[j]){i++;j++;}else{// S的指针跳到下一个字符位置i = i - j + 1;j = 0;}}//若T的指针j扫描到最后一个元素说明都匹配上就返回第一个匹配上的地址if (j == T.length)return i - j;elsereturn 0;
}

串的模式匹配算法—KMP算法

上方的暴力匹配算法中有许多重复的趟数会导致花不必要的时间来跑已经知道的结果,KMP算法就是用于解决这个问题,在KMP算法中,会采用一个next数组来记录子串是在主串第几个元素匹配失败的,下次可以通过next来直接重匹配失败的位置重新开始匹配。在KMP算法中,最主要的就是next数组的计算。

//S和T数组下标由1开始
// KMP算法 若主串S中存在与串T值相同的字串,则返回它在S中第一次出现的位置,否则为0
int Index_KMP(SString S, SString T, int next[])
{// i和j分别为S和T的计数指针int i = 1, j = 1;if (S.length == 0 || T.length == 0)return 0;while (i <= S.length && j <= T.length){if (S.ch[i] == T.ch[j] || j == 0){i++;j++;}else{// KMP算法只需根据计算出的next数组对j的值进行修改j = next[j];}}// 若T的指针j扫描到最后一个元素说明都匹配上就返回第一个匹配上的地址if (j > T.length)return i - T.length;elsereturn 0;
}

// 求next数组
void get_next(SString T, int next[])
{int i = 1, j = 0;next[0] = 0;while (i < T.length){if (j == 0 || T.ch[i] == T.ch[j]){++i;++j;next[i] = j;}elsej = next[j];}
}

http://www.ppmy.cn/server/157542.html

相关文章

el-descriptions-item使用span占行不生效

需要实现的效果是客户状态单独占满一行 错误代码&#xff1a; <el-descriptions title"基本信息" :column"3"> <el-descriptions-item label"公司电话:">Suzhou</el-descriptions-item><el-descriptions-item label"…

【Rust自学】11.7. 按测试的名称运行测试

喜欢的话别忘了点赞、收藏加关注哦&#xff08;加关注即可阅读全文&#xff09;&#xff0c;对接下来的教程有兴趣的可以关注专栏。谢谢喵&#xff01;(&#xff65;ω&#xff65;) 11.7.1. 按名称运行测试的子集 如果想要选择运行的测试&#xff0c;就将测试的名称&#x…

使用Python爬虫获取淘宝商品详情接口

以下是一篇关于使用Python获取淘宝商品详情接口的长篇文章&#xff1a; 淘宝商品详情接口简介 淘宝商品详情接口是淘宝开放平台提供的API之一&#xff0c;用于获取淘宝商品的详细信息。它可以帮助开发者获取商品的标题、价格、图片、库存、销量、评价等数据。这些数据对于电商…

理解Unity脚本编译过程:程序集

https://docs.unity3d.com/Manual/script-compilation.html 关于Unity C#脚本编译的细节&#xff0c;其中一个比较重要的知识点就是如何自定义Assembly。 预定义的assembly 默认情况下&#xff0c;Unity会按照这个规则进行编译。 PhaseAssembly nameScript files1Assembly-…

数组分割函数

这是一个数组分割函数&#xff0c;它的作用是将一个大数组按照指定的长度分割成多个小数组。 参数说明&#xff1a; array: 需要被分割的原始数组 subGroupLength: 每个小数组的长度 工作原理&#xff1a; splitArray(array, subGroupLength) {let index 0; …

二次雷达的详细介绍及代码示例

一、二次雷达的工作原理 二次雷达&#xff0c;又称空管雷达信标系统&#xff08;Air Traffic Control Radar Beacon System&#xff0c;ATCRBS&#xff09;&#xff0c;是一种无线电电子测位和辨认系统。它由地面询问雷达和飞机上的应答雷达&#xff08;又称雷达信标&#xff0…

Helm部署activemq

1.helm create activemq 创建helm文件目录 2.修改values.yaml 修改image和port 3. helm template activemq 渲染并输出 4. helm install activemq activemq/ -n chemical-park // 安装 5.启动成功

CSS语言的数据库交互

CSS语言的数据库交互&#xff1a;一种新潮流的探索 引言 在现代网页开发中&#xff0c;CSS&#xff08;层叠样式表&#xff09;无疑是构建优美和响应式网页的重要工具。然而&#xff0c;关于CSS和数据库之间的直接交互&#xff0c;尽管并不是一种常见的做法&#xff0c;却引发…