C语言标准函数库中包括 strstr 函数,在主串中查找子串。作为练习,我们自己编写一个功能与之相同的函数。
函数原型
char* StrStr(const char *txt, const char *pat);
说明:txt
和 pat
分别为主串和子串的起始地址。若查找成功,则函数值为子串在主串中首次出现的起始地址,否则函数值为NULL。
特别地,我们对C语言库函数strstr进行适当修改:若子串为空串,则没有意义,函数值规定为NULL。
裁判程序
#include <stdio.h>
#include <string.h>
char* StrStr(const char *txt, const char *pat);
int main() {
char m[1024], s[1024], *p;
gets(m);
gets(s);
p = StrStr(m, s);
if (p) {
printf("%d\n", p - m);
}
else {
puts("NULL");
}
return 0;
}
/* 你提交的代码将被嵌在这里 */
输入样例1
This is a pencil
is
输出样例1
2
输入样例2
This is a pencil
be
输出样例2
NULL
分析:
- 检查 pattern(即第二个参数 pat)是否为空。如果为空,则返回 NULL。
- 使用一个 while 循环遍历主字符串(txt)。在主循环中,我们使用两个内部指针(t 和 p)分别遍历主字符串和模式字符串。
- 在内部循环中,如果两个指针所指向的字符相同,并且模式字符串(pat)的当前字符不是 '\0',那么就将两个指针都向前移动一位。
- 如果模式字符串(pat)遍历结束(即遇到 '\0'),那么返回主字符串(txt)的当前位置。这个位置就是模式字符串在主字符串中第一次出现的位置。
- 如果在内部循环中,主字符串(txt)的当前字符和模式字符串(pat)的当前字符不同,或者模式字符串(pat)还没有遍历结束,那么就将主字符串(txt)的指针向前移动一位,然后回到步骤 2。
- 如果主字符串(txt)遍历结束,那么返回 NULL。
C语言:
char* StrStr(const char *txt, const char *pat)
{
if (*pat == '\0')
return NULL;
while (*txt != '\0') {
const char *t = txt;
const char *p = pat;
while (*t == *p && *p != '\0') {
t++;
p++;
}
if (*p == '\0')
return (char*) txt;
txt++;
}
return NULL;
}
总结:
这是一个使用朴素的字符串匹配算法实现的函数。算法的基本思想是遍历主字符串,并在每个位置尝试匹配模式字符串。如果找到匹配,返回模式字符串在主字符串中第一次出现的位置。如果没有找到匹配,继续遍历主字符串。这个算法的时间复杂度是 O(n*m),其中 n 是主字符串的长度,m 是模式字符串的长度。