一、串的概述
啥是串?串是由0个或多个字符组成的有限序列,又名叫字符串。串其实是一种非数值表示方式,其实非数值和数值的转换主要是通过ASCII码表的对应关系。0个字符组成的串叫作空串,直接由“ ”表示,或者用来表示。
子串和主串:“abc"是”abcdef"的子串,“abcdef"是"abc"的主串。
字符串比较大小:将字符串中每个字符的ASCII码相加之和进行比较。
串的顺序存储结构是用一组地址连续的存储单元来存储串中的字符序列。与线性表相似,存储区为固定长度,空间分配不灵活。
因为字符串一般都是连在一起表述,随机抽出任意几个位置字符的情况不多,所以习惯上通常会定义一个足够长度存储区来存储串。
二、子串定位(串的模式匹配)算法
1、BF算法
S为主串,长度为N;T是子串,长度为M;
首先S【1】和T【1】比较,若相等,则再比较S【2】和T【2】,一直到T【m】为止;若S【1】和T【1】不等,则T向右移动一个字符位置,再比较T【1】与S【2】。
算法最坏情况进行M*(N-M+1)次比较,时间复杂度为O(M*N)
2、KMP算法
KMP算法也是应用于模式匹配的一种算法,不过不像BF算法,对应字符不等就一个一个比下去这样低效率,KMP算法通过next数组,在模式串某个字符不匹配时会指示从模式串哪个位置开始回溯,从而提高了效率。
next数组:当模式匹配串T失配,next数组对应的元素指导应该从哪个位置开始下一轮匹配。
下面通过一个例子,来介绍next数组的确定。
上面是一个模式串,next数组即为标记为k的数组,模式串数组即为T数组,模式串各个字符所处位置即为j数组。
首先next数组的第1个元素一定为0,第2个元素一定为1,之后的元素由模式串对应字符确定。
首先我们还要了解什么是前缀和后缀。
前缀和后缀都不包括整个字符串!!
假设:1 2 3 4 5 6 7 8 9这样一列数
3的前缀是1,后缀是2
4的前缀是1 2或1,后缀是2 3或3
5的前缀是1 2 3或1 2或1,后缀是2 3 4或3 4或4
6的前缀是1 2 3 4或1 2 3 或1 2或1,后缀是2 3 4 5或3 4 5或4 5或5
········
next数组的元素就是对应元素前缀与后缀中相同字符的最大个数!
第3个字符为a,前缀为a,后缀为b,最多0个相同,填0+1=1
第4个字符为b,前缀为ab或a,后缀为ba或a,最多1个相同,填1+1=2
第5个字符为a,前缀为aba或ab或a,后缀为bab或ab或b,最多2个相同,填2+1=3
第6个字符为a,前缀为abab或aba或ab或a,后缀为baba或aba或ba或a,最多3个相同,填3+1=4
第7个字符为a,前缀为ababa或abab或aba或ab或a,后缀为babaa或abaa或baa或aa或a,最多1个相同,填1+1=2
第8个字符为a,前缀为ababaa或ababa或abab或aba或ab或a,后缀为babaaa或abaaa或baaa或aaa或aa或a,最多1个相同,填1+1=2
//next数组代码
void get_next(String T,int *next)
{
int i=1,j=0;
next[1]=0;
while(i { if(j==0||T[i]==T[j]) { i++; j++; if(T[i]!=T[j]) { next[i]=j; } else { next[i]=next[j]; } } else { j=next[j]; } } } BY ZJQ