strstr 函数用于在目标字符串中查找子串。模拟实现时,使用的仅仅只是简单版本的,并非KMP算法。函数声明如下:
1、参数返回值解析
第一个参数:目标字符串
第二个参数:子串
返回值:返回子串在目标字符串中首次出现的地址,如果目标字符串没有找到子串,则返回NULL
2、函数模拟实现
在模拟实现的时候,首先需要的是两个用于比较的指针dst 和 substr,每一轮的匹配都是靠这两个指针比较的。
================比对成功================
比对成功:
- dst 向后移动:dst ++
- substr向后移动:substr ++
- 最理想的情况:dst没有结束,substr已经先遇到了'\0',说明子串所有字符都已经比较完毕,此时需要返回主串中,上一次可能匹配成功的位置。
================比对失败================
比对失败以后,dst 要从哪里开始,substr从哪里开始,这里就又需要两个指针 start1 和 start2,一个指向主串上一次可能匹配成功的位置,一个指向子串的起始位置。
- start1 一开始指向的是 dst的起始位置,start2一直都指向 substr的起始位置
- 当 *dst != *substr 的时候,说明当前位置无法匹配成功,这个时候就比对失败了
- 此时需要更新 “可能匹配成功的位置” start1:start1++
- substr回到起始位置:substr = start2;
- dst 去往下一个start1所在的位置:dst = start1
char* my_strstr(const char* dst, const char* substr)
{
assert(dst);
if (substr == NULL)
return (char*)dst;
char* start1 = (char*)dst; // 上一次可能匹配成功的起始位置(一直在变化)
char* start2 = (char*)substr; // 子串每次匹配不成功时的起始位置(不变的)
while (*start1 != '\0') // 主串都到末尾了还没找到,那就说明主串里不包含这个子串
{
// 比较相等,主串和子串指针继续向后比较,主串最近匹配位置更新
while (*dst == *substr)
{
dst++;
substr++;
if (*substr == '\0')
{
return start1;
}
continue;
}
// 更新可能匹配成功的起始位置
start1++;
// 比较不相等,子串回到起点;主串回到上一次匹配位置的下一个位置
substr = start2;
dst = start1;
}
return NULL;
}
int main() {
char* dst = "abbcbbde";
char* substr = "bbs";
char* ret = my_strstr(dst, substr);
if (ret == NULL)
{
printf("没有找到\n");
}
else
{
for (size_t i = 0; i < strlen(substr); i++)
{
printf("%c ", *(ret + i));
}
}
return 0;
}