串(C语言实现)
串的逻辑结构和线性表极为相似,区别仅在于串的数据对象约束为字符集。这里主要介绍一下串的数据类型定义,存储结构,以及串的模式匹配算法——BF 算法和 KMP 算法。
1.串的数据类型定义
数据对象
- D = { ai | ai ∈ CharacterSet, i = 1, 2, …, n, n ≥ 0 }
1.1 数据关系
- R1 = { < ai, aj > | i < j, ai, aj ∈ D, i = 2, …, n }
1.2 基本操作
| 操作名称 | 初始条件 | 操作结果 |
|---|---|---|
| StrAssign(&T, chars) | chars 是字符串常量。 | 生成一个其值等于 chars 的串 T。 |
| StrCopy(&T, S) | 串 S 存在。 | 由串 S 复制得串 T。 |
| StrEmpty(S) | 串 S 存在。 | 若 S 为空串,则返回 true;否则返回 false。 |
| StrCompare(S, T) | 串 S 和 T 存在。 | 若 S > T, 则返回值 > 0; 若 S = T, 则返回值 = 0; 若 S < T, 则返回值 < 0。 |
| StrLength(S) | 串 S 存在。 | 返回 S 的元素个数,称为串的长度。 |
| ClearString(&S) | 串 S 存在。 | 将 S 清为空串。 |
| Concat(&T, S1, S2) | 串 S1 和 S2 存在。 | 用 T 返回由 S1 和 S2 连接而成的新串。 |
| SubString(&Sub, S, pos, len) | 串 S 存在,1 ≤ pos ≤ StrLength(S) 且 0 ≤ len ≤ StrLength(S) - pos + 1。 | 用 Sub 返回串 S 的第 pos 个字符起长度为 len 的子串。 |
| Index(S, T, pos) | 串 S 和 T 存在,T 是非空串,1 ≤ pos ≤ StrLength(S)。 | 若主串 S 中存在和串 T 值相同的子串,则返回它在主串 S 中第 pos 个字符之后第一次出现的位置;否则函数值为 0。 |
| Replace(&S, T, V) | 串 S, T 和 V 存在,T 是非空串。 | 用 V 替换主串 S 中出现的所有与 T 相等的不重叠的子串。 |
| StrInsert(&S, pos, T) | 串 S 和 T 存在,1 ≤ pos ≤ StrLength(S) + 1。 | 在串 S 的第 pos 个字符之前插入串 T。 |
| StrDelete(&S, pos, len) | 串 S 存在,1 ≤ pos ≤ StrLength(S) - len + 1。 | 从串 S 中删除第 pos 个字符起长度为 len 的子串。 |
| DestroyString(&S) | 串 S 存在。 | 串 S 被销毁。 |
2.串的存储结构
2.1 串的顺序存储
// 串的顺序存储结构
#define Max_Size 255 //串的最大长度
typedef struct String{
char ch[Max_Size+1];
int length;
}SString;
其中,Max_Size 表示串的最大长度,ch 是存储字符串的一维数组,每个分量存储一个字符,length 表示字符串的当前长度。为了符合习惯,一般将下标为 0 的数组闲置不用,尽量从 1 开始。
2.2 串的链式存储
// 串的链式存储
typedef struct LNode{
char *ch;
struct LNode *next;
}LinkList;
typedef struct {
LinkList *head,*tatial; //串的头尾指针
int length;
}LString;
顺序串的插入和删除操作不方便,需要移动大量的字符。因此, 可采用单链表方式存储串。
3.串的模式匹配算法
子串的定位运算通常称为串的模式匹配或串匹配。此运算的应用非常广泛,比如在搜索引擎、拼写检查、语言翻译、数据压缩等应用中, 都需要进行串匹配。
串的模式匹配设有两个字符串 S 和 T, 设 S 为主串,也称正文串;设 T 为子串,也称为模式。在主串 S 中查找与模式 T 相匹配的子串,如果匹配成功, 确定相匹配的子串中的第一个字符在主串 S 中出现的位置。
著名的模式匹配算法有 BF 算法和 KMP 算法,下面详细介绍这两种算法。
3.1BF 算法
BF 算法是经典的暴力解法,子串 T 与 S 逐个匹配,相同就往后走,不相同就回溯。这个算法最好情况下时间复杂度为 O(n+m),最坏情况下为 O(m*n)。具体代码如下
// BF算法
int Index_BF(SString S, SString T, int pos){
// 返回模式T在主串s中第pos个字符开始第一次出现的位置。若不存在, 则返回值为0
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 + 2;
j = 1; //回溯
}
}
if(j > T.length){
return i - T.length; //匹配成功
}
return 0;
}
3.2KMP 算法
KMP 算法可以在 O(n+m)的时间数量级上完成串的模式匹配操作。其改进在千:每当一趟匹配过程中出现字符比较不等时,不需回溯 l 指针,而是利用已经得到的”部分匹配" 的结果将模式向右"滑动“ 尽可能远的一段距离后,继续进行比较。
// 获取next数组
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];
}
}
}
//KMP算法
int Index_KMP(SString S, SString T, int pos, int next){
int i = pos;
int j = 1;
while (i <= S.length && j <= T.length){
if(S.ch[i] == T.ch[j]){
i++;
j++;
}
else{
j = next[j];
}
}
if(j > T.length){
return i - S.length;
}
return -1;
}
前面定义的 next 函数在某些情况下尚有缺陷;例如模式"aaaab" 在和主串"aaabaaaab"匹配时,当 i = 4 、j= 4 时 s.ch [ 4] -:t:- t.ch [ 4] , 由 next(j) 的指示还需进行 i = 4 、j= 3, i = 4 、j= 2, i = 4 、j=l 这 3 次比较。因此,需要我们对 next 进行修正。
// 修正next数组
void Get_Nextval(SString T, int nextval[]){
int i = 1;
nextval[0] = 0;
int j = 0;
while (j <= T.length){
if(j == 0 || T.ch[i] == T.ch[j]){
i++;
j++;
if(T.ch[i] == T.ch[j]){
nextval[i] = nextval[j];
}
else{
nextval[i] = j;
}
}
else{
j = nextval[j];
}
}
}
以上就是串的全部内容,如有错误请联系 QQ:303623518
串(C语言实现)的更多相关文章
- 010-字符串-C语言笔记
010-字符串-C语言笔记 学习目标 1.[掌握]二维数组的声明和初始化 2.[掌握]遍历二维数组 3.[掌握]二维数组在内存中的存储 4.[掌握]二维数组与函数 5.[掌握]字符串 一.二维数组的声 ...
- 周期串(JAVA语言)
package 第三章习题; /* * 如果一个字符可以由某个长度为k的字符串重复多次得到,则称该串以k为周期. * 例如:abcabcabcabc 以3为周期(注意:它也以6和12为周期) * ...
- 自动机理论、语言和计算导论 by John E. Hopcroft
计算理论是计算机应用的基础,理论和应用缺一而不可. ---- 目录 ---- C01 自动机 C02 有穷自动机 C03 正则表达式与正则语言 C04 正则语言的性质 C05 上下文无关文法及上下文无 ...
- 【接口时序】2、Verilog实现流水灯及与C语言的对比
一. 软件平台与硬件平台 软件平台: 1.操作系统:Windows-8.1 2.开发套件:ISE14.7 3.仿真工具:ModelSim-10.4-SE 硬件平台: 1.FPGA型号:XC6SLX45 ...
- 【转】iOS多语言本地化(国际化)设置
原文网址:http://www.jianshu.com/p/2b7743ae9c90 讨论的iOS应用中的多语言设置,Ok 一般是两种情况: 1.根据当前设备语言自动切换显示 2.在应用中可进行语言设 ...
- Compiler Theory(编译原理)、词法/语法/AST/中间代码优化在Webshell检测上的应用
catalog . 引论 . 构建一个编译器的相关科学 . 程序设计语言基础 . 一个简单的语法制导翻译器 . 简单表达式的翻译器(源代码示例) . 词法分析 . 生成中间代码 . 词法分析器的实现 ...
- MPI简介
什么是MPI: MPI是一个库,而不是一门语言.但是按照并行语言的分类,可以把FORTRAN+MPI或者C+MPI看作是一种在原来串行语言基础上扩展后得到的并行语言.MPI库可以被FORTRAN77/ ...
- Android jni 编程1(对基本类型字符串的操作)
最近一直在学安卓的jni,主要参考的是黑马程序员的视频教程,讲的确实不错. 那就自己总结一下吧,算是对学习的复习. 这篇博客也主要参考了这位博主:http://www.cnblogs.com/acti ...
- win 10 在vs2017下对mpi的安装以及认识
这里我先对MPI进行一下简单的介绍,MPI的全称是Message Passing Interface,即消息传递接口. 它并不是一门语言,而是一个库,我们可以用Fortran.C.C++结合MPI提供 ...
- mpi4python
转载:https://zhuanlan.zhihu.com/p/25332041 前言 在高性能计算的项目中我们通常都会使用效率更高的编译型的语言例如C.C++.Fortran等,但是由于Python ...
随机推荐
- python语言绘图:绘制贝叶斯方法中最大后验密度(Highest Posterior Density, HPD)区间图的近似计算(续)
代码源自: https://github.com/PacktPublishing/Bayesian-Analysis-with-Python 内容接前文: python语言绘图:绘制贝叶斯方法中最大后 ...
- 一些八股:1.fetch 的理解。2.let、const、var
一. 说说你对 Fetch 的理解,它有哪些优点和不足? Fetch API 是现代 JavaScript 中用于进行网络请求的接口,旨在替代传统的 XMLHttpRequest.它提供了一种更简单. ...
- spring创建 JavaWeb
- AtCoder Beginner Contest 329 F
AtCoder Beginner Contest 329F F - Colored Ball (atcoder.jp)(启发式合并) 问题陈述 有 \(N\) 个编号为 \(1, 2, \ldots, ...
- 互联工厂数据交换标准:IPC-CFX
大家好,我是Edison. 全球电子制造主要集中在中国,面向未来工业4.0.中国制造2025的战略转型升级,互联互通是基础.数据是核心,如何从用户角度来定义设备加工数据的内容完整性.有效性.可扩展性将 ...
- mysql where 字符串根据英文逗号分割为数组 并判断是否包含指定字符串
SELECT * FROM table_name where FIND_IN_SET('A',column_1) or FIND_IN_SET('B', column_2) table_name : ...
- iptables 命令使用帮助总结
本文为博主原创,转载请注明出处: 1.iptables 命令帮助参数 root@controller1:~# iptables --help iptables v1.6.1 Usage: iptabl ...
- SPSS25.0中文破解版安装教程及使用教程
目录 第一步,下载链接: 下载并解压,管理员身份运行SPSS 25 64bit.exe: 第二步,安装过程一路默认,安装路径可以改变,然后等待安装完成即可: 第三步,安装完成后,立即启动SPPS; 第 ...
- Coursera, Big Data 5, Graph Analytics for Big Data, Week 4
Graph Analytics With Neo4j 讲了怎样用Cypher 脚本语言去操作 Neo4j, 包括加graph, 导入csv数据. 接着讲了一些neo4j 的基本操作. 最后讲的,pat ...
- webpack系列-webpack内置插件ProvidePlugin的应用(定义全局变量,例如vue引入jquery全局使用)
vue+webpack使用ProvidePlugin插件引入jquery 先看一个实例,webpack+vue引入jquery并全局使用,这儿指通过配置,不是在静态页面使用script标签直接引入jq ...