数据结构---串
来源:互联网 发布:c语言结构 编辑:程序博客网 时间:2024/04/29 06:48
串:
由零个或多个字符构成的有限序列,又叫字符串
一般记为:s=”a1a2a3……an”
子串和主串:
串中任意个数的连续字符组成的子序列称为该串的子串 子串在主串中的位置就是子串的第一个字符在主串中的序号
串的比较:
给定两个串:s=”a1a2a3……an”,t=”b1b2b3……bm”,当满足以下条件之一时,s
串的存储结构:
顺序存储结构:
用一组地址连续的存储单元来存储串中的字符序列。
按照预定义的大小,为每个定义的串变量分配一个固定长度的存储区,一般是用定长数组来定义
数组中也会存储预定义的最大串长度,一般可以将串的长度放在数组0处,或者数组最后,或者规定在串的最后加一个终结符,比如“\0”(表示串的结束)
缺点:
对于一些对字符串的操作(改变字符串长度),比如两串的连接Concat、新串的插入等操作,都有可能使得串序列的长度超过了数组长度MaxSize,会与定长冲突
链式存储结构:
一个结点可以存放一个字符,也可以存放多个字符,最后一个结点若是没有被占满,可以用”#”或其他非串值字符补全
链式存储结构在连接串上方便,但是不如顺序存储灵活,性能也不如顺序存储结构
串的操作:
不同的编程语言有不同的串操作,不过大体上是一样的,接触语言时可以看看API
模式匹配算法:
朴素的模式匹配算法:
1) 从主S的第一个字符起和子串T的第一个字符进行比较,若相等,则继续逐个比较主串和子串的后续字符,否则从串主串S的下一个字符起再重新和子串T进行比较。
2) 依此类推,直至子串T中的每个字符依次和主串S的一个连续的字符序列相等,则称模式匹配成功,此时子串T的第一个字符在主串S中的位置就是T在S中的位置,否则模式匹配不成功。
/** * S : 主串 * T : 子串 * pos : 从pso位置后面开始匹配 * 注意:数组的0位置存储数组的长度 */int index(String S, String T, int pos){ int i = pos; // i是主串字符上的指针 int j = 1; // j是子串当前位置 while(i <= S[0] && j <= T[0]) { // 字符匹配成功,匹配下一个字符 if(S[i] == T[j]) { ++ i; ++ j; } // 字符匹配失败 else { i = (i-j+1) + 1; // 主串指针回到开始匹配位置的下一个位置 j = 1; // 子串指针回到开始 } } // 子串匹配成功 if(j > T[0]) return i - T[0]; // 子串匹配失败 else return 0;}
KMP模式匹配算法:
i:主串和子串比较时,主串当前位置的下标
主串和子串比较时,不用回溯i指针(不可以变小)
举例:
主串S=”abcababca”,子串T=”abcabx”
第1步:对于开始的比较,前5个字符相等,
第4步:T的首位”a”与T的第四位的”a”相等,后面的”b”也相等。
而在第1步的时候,第四位的”a”和第五位的”b”已经和主串中相应的位置已经比较为相等,所以T的首字符”a”和下一位的”b”就不需要再比较了。
在这里,我们只要确定T串中各个位置的j值的变化定义为一个数组next,那么next的长度就是T串的长度。
注:p1,p2,…,pj-1是T串每个位置上的元素
注意:
第二种情况确定j,可以利用前缀字符和后缀字符相等的字符数n个(j=n+1)
1. 当j=1时,next[1]=0
2. 当j=2时,j由1到j-1的串是”a”,next[2]=1
3. 当j=3时,j由1到j-1的串是”ab”,next[3]=1
4. 当j=4时,j由1到j-1的串是”aba”,前缀字符”a”与后缀字符”a”相等,所以next[4]=1
5. 当j=5时,j由1到j-1的串是”abab”,前缀字符”ab”与后缀字符”ab”相等,所以next[5]=3
6. 当j=6时,j由1到j-1的串是”ababa”,前缀字符”aba”与后缀字符”aba”相等,所以next[6]=4
7. 当j=7时,j由1到j-1的串是”ababaa”,前缀字符”a”与后缀字符”a”相等,所以next[7]=2
8. 当j=8时,j由1到j-1的串是”ababaaa”,前缀字符”a”与后缀字符”a”相等,所以next[8]=2
9. 当j=9时,j由1到j-1的串是”ababaaab”,前缀字符”ab”与后缀字符”ab”相等,所以next[9]=3
算法实现:
通过计算返回子串T的next数组:
void getNext(String T, int *next){ int i, j; i = 1; j = 0; next[1] = 0; while(i < T[0]) // 0处存放数组长度 { if(j == 0 || T[i] == T[j]) { ++ i; ++ j; next[i] = j; } else{ j = next[j]; } }}
返回子串T在主串S中第pos个字符后的位置
int index(String S, String T, int pos){ int i = pos; // i指示主串S的位置 int j =1; // j指示子串T的位置 int next[255]; // 定义一个next数组 getNext(T, next); // 获取T的next数组 while(i <= S[0] && j <= T[0]) // S[0]和T[0]存放数组长度 { if(j == 0 || S[i] == T[j]) // 两字母相等就继续 { ++ i; ++ j; } else // 指针后退重新比较 { j = next[j]; // j退回合适的位置,i值不变 } } if(j > T[0]) return i - T[0]; else return 0;}
- 数据结构,串
- 数据结构---串
- 数据结构--串
- 数据结构-串
- 数据结构 串
- 数据结构 串
- 【数据结构】串
- 数据结构--串
- 【数据结构】-串
- 数据结构----串
- 数据结构-串
- 数据结构:串
- [数据结构]串
- [数据结构]串
- 数据结构--串
- 数据结构---串
- 数据结构----串
- 数据结构:串
- 高阶Java枚举类型enum使用详解
- Swift使用代码进行约束
- IntellJ Idea创建Maven Jetty Web项目
- 【Mybatis框架】查询缓存(二级缓存)
- oracle函数trunc的使用
- 数据结构---串
- LA 4726 Average (单调队列+斜率优化)
- 电力系统可视化图形建模系统V1.2
- Android屏幕适配全攻略(最权威的官方适配指导)
- Android NDK系列(5) — SO中获取Java对象的属性
- CentOS 中用 Split 命令分割文件的方法
- 各种开发语言比较
- 学习笔记:MapReduce理解
- Elasticsearch query_string语法查询