字符串是由零个或多个字符组成的有限序列,一般记为:
S = “a1 a2 a3 ···an”(n
≥
\geq
≥ 0)
其中,S是字符串的名,用引号括起来的字符序列是字符串的值:ai(1 ≤ \leq ≤ i ≤ \leq ≤ n)可以是字母、数字或其他字符;字符串中字符的数目n称为字符串的长度。零个字符的字符串称为空字符串。
字符串中任意个连续的字符组成的子序列称为该字符串的子字符串。包含子字符串的字符串相应地称为主串。通常称字符在序列中的下标为该字符在串中的位置。子字符串在主串中的位置则以子字符串的第一个字符在主串中的位置表示。
字符串匹配
1. 朴素的字符串匹配算法
朴素的字符串匹配,就是给定一个字符串(s)(小于等于要匹配主串的长度),然后从主串(m)的第一个字符开始依次与s根据字符串相等的概念去匹配,找到则匹配成功。
示例:
int string_match(char* target, char* patten) {
int t1 = strlen(target);
int p1 = strlen(patten);
int i = 0;
int j = 0;
while(i < t1 - p1 && j < p1) {
if(pattten[j] == target [i + j])
j++;
else {
j = 0;
i++;
}
}
if(j == p1)
return i;
return -1;
}
可以看见,这个算法(假定m >> n)的复杂度是O(mn),其中m是T的长度,n是P的长度。这种算法的缺陷是匹配过程中带有回溯——准确地说是T串存在回溯,也就是当匹配不成功的时候,之前进行的匹配完全变为无用功,所有的比较需要重新开始。
2. KMP算法
与普通匹配算法不同的是,KMP算法在子串匹配失效的时候,下一步并不是重新从子串的头部开始匹配,而是根据next函数计算出下一步应该从子串的什么位置开始匹配。
KMP算法的思想比较复杂,在此略过,有兴趣的可以查找相关资料。
3. 其他匹配算法
字符串处理算法还有很多,如Rabin-karp、有限自动机、正则表达式、后缀树算法等,在此也不一一列举,有兴趣的可以查找相关资料。