目录
1. Locate substring
#include <string.h>
char * strstr ( const char * str1, const char * str2 );
Returns a pointer to the first occurrence of str2 in str1, or a null pointer if str2 is not part of str1.The matching process does not include the terminating null-characters, but it stops there.
上述内容是 cplusplus 对 strstr 函数的介绍,可以看出 strstr 函数返回指向 str1 中 str2 第一次出现的指针,如果 str2 不是 str1 的一部分,则返回空指针。
需要注意的是,匹配过程中不包含 NULL 空字符。
2. 算法分析
- 首先需要判断字符串 str1 的首字符是否与 str2 中的首字符相同
- 如果不相同的话,str1 指向的字符向后移动,不断地去比较 str1 的字符与 str2 中的首字符
- 如果一直都不相同的话,就表示 str1 中找不到包含 str2 的字符串
- 如果相同的话,那么 str1 和 str2 指向的字符都向后移动
- 再次判断 str2 中的字符串是否全都在 str1 中出现
- 如果是的话,那么返回 str2 在 str1 中的位置
- 如果不是全都出现的话,那么表示没有找到,返回 NULL
- 再次判断 str2 中的字符串是否全都在 str1 中出现
需要注意的是,匹配到首个字符时,有可能是连续几个字符相同的情况,这时就需要判断 str2 中的字符匹配 str1 时,究竟是 str1 中的哪个字符才是需要匹配的首个字符。
这里举例说明下,若 str1 内容为 "abcccde",str2 内容为 "cd",那么指向 str1 中的第三个字符 'c' 时,恰巧 str2 中的首个字符为 'c',这时可以认为匹配到首个字符。但是当 str1 后移一个字符时,即就是 'c',而 str2 后移一个字符,即就是 'd',显然不匹配了,但是并不能认为 str1 中没有匹配 str2 的项,这就需要在匹配前保存遇到的 str2 中的首个字符在 str1 中的位置,方便下一次查找(也就是不需要再次遍历了)。当指向 str1 中的第二个 'c' 时,匹配 str2 中的首个字符 'c',此时 str1 后移一位,即就是 'c' ,而 str2 后移一个字符,即就是 'd',显然不匹配了,由于保存了 str1 中第二个 'c' 的位置,那么接下来就可以从 str1 中的第三个 'c' 开始匹配,str2 中首个字符为 'c',str1 后移一位,即就是 'd',而 str2 后移一位也是 'd',str1 再次后移一位得到 'e',而 str2 后移一位得到 '\0',查找结束。
3. 源代码
#include <stdio.h>
#include <assert.h>
char * MyStrstr(const char *src, const char *substr) {
const char *str1 = src;
const char *str2 = substr;
assert((NULL != src) && (NULL != substr));
if ('\0' == *str2) {
return (char *)src;
} else {
while ('\0' != *src) {
str1 = src;
str2 = substr;
while (('\0' != *str1) && ('\0' != *str2) && (*str1 == *str2)) {
str1++;
str2++;
}
if ('\0' == *str2) {
return (char *)src;
} else {
src++;
}
}
}
return NULL;
}
int main(void) {
char * str = "abbbcde";
char * substr = "bbcd";
char * ret = MyStrstr(str, substr);
printf("str: %s\n", str);
printf("substr: %s\n", substr);
if (NULL != ret) {
printf("找到了子字符串,其在源字符串中的内容为: %s\n", ret);
} else {
printf("没找到子字符串!\n");
}
return 0;
}