串概念
408对串概念不做要求,只需要掌握匹配算法。这部分了解即可。
基本概念
串(string):由零个或者多个字符组成的有限序列。
子串:串中任意个连续的字符组成的子序列
字符在串中的位置:字符在串中的序号
子串在串中的位置:子串的第一个字符在串中的第一个位置
所有位置都是从1开始与位序这个概念相同
串实际上与线性表非常相像,不同点:
- 线性表的内容为元素,只要结构相同可以是任何东西,但串只能是字符
- 线性表针对的增删改查的操作都是针对元素,而串这类操作大多数情况下都是针对子串
串的结构
串符合线性表三要素,可以看成是一种特殊线性表,所以可以使用线性表的各种存储方式,顺序存储,链式存储都可以。使用的优缺点对应于顺序表于链表。
串逻辑存储上主要有三种方式:
- 为一个结构体,包含一个char数组于一个数值变量用于存储串长度。
- 只用char数组表示,但char[1]开始存放串,char[0]存放串长度。优点:位序与数组标相同。缺点串最大不超过255.
- 不特殊存储串长度,用’\0’表示串结构
王道课本采用1,2结合方式。即使用第一种,但char数组从char[1]开始存放,char[0]不存东西。
模式匹配
有两个串,假设为A,B。寻找A中是否包含B这个子串就叫做模式匹配。A称为主串,B称为模式串。
408大纲对串的要求掌握朴素模式匹配和KMP算法,这两个都是进行串匹配操作。
朴素模式匹配
算法过程:
- 遍历主串每一个元素,每一元素都作为串匹配的起始点。
- 从起始点开始往下匹配匹配串串长个长度,如果都相同,说明子串中有匹配串,返回true。否则说明以该起点作为起始点的子串不可能与匹配串相同,将主串的起始点往下一一个单位。
代码
//写法1,没啥好说的,常规写法
bool stringMatch(String s1, String s2){
for (int i = 1; i <= s1.length ; i ++){
if (s1.length - i + 1 < s2.length)
break;
bool jud = true;
for (int j = 1 ; j <= s2.length ; j ++)
if (s1.data[i + j-1] != s2.data[j]){
jud = false;
break;
}
if (jud)
return true;
}
return false;
}
//写法2
bool stringMatch(String s1, String s2){
int i = 1; //主串指针
int j = 1; //匹配串指针
while (i <= s1.length && j <= s2.length){
if (s1.data[i] == s2.data[j]){ //如果相等,两个指针后移
i++;
j++;
} else { //如果不相等,主串指针需要移回到匹配初始点的下一个。
i = i - j + 2; //此时的j就代表了在一次匹配中检测了多少个字符,i-j+1就移回到了匹配初始点。
j = 1;
}
//如果匹配成功j就会超过s2.length就会跳出循环。
}
return j == s2.length+1;
}