28. 实现 strStr()
题目描述: 实现 strStr() 函数。
给定一个 haystack 字符串和一个 needle 字符串,在 haystack 字符串中找出 needle 字符串出现的第一个位置 (从0开始)。如果不存在,则返回 -1。
示例 1:
输入: haystack = "hello", needle = "ll"
输出: 2
- 暴力法:双层循环,判断needle字符串是否在haystack里
int strStr(char * haystack, char * needle){
if(needle == NULL) return 0; //判断needle是否为空字符串
//暴力法:
int i, j, hayLen = strlen(haystack), neeLen = strlen(needle);
char *p;
p = haystack;
for(i = 0; i <= hayLen - neeLen; i++){
p += i;
for(j = 0; j < neeLen; j++){
if(needle[j] != *p) break;
else p += 1;
}
if(j == neeLen) return i;
else p = haystack;
}
return -1;
}
//还可以这样写
int strStr(char * haystack, char * needle){
int len1 = strlen(haystack);
int len2 = strlen(needle);
int flag = 0;
if(len1==0 && len2==0){
return 0;
}
for(int i = 0; i < len1; i++){
flag = 0;
for(int j = 0;j < len2; j++){
if(haystack[i + j] != needle[j]){
flag = 1;
break;
}
}
if(flag == 0){
return i;
}
}
return -1;
}
- 典型做法:KMP,这篇讲的相对明白点,https://blog.csdn.net/yyzsir/article/details/89462339
主要是分两步:
一 是求next数组(最大公共前后缀);
二 是比较模式串和主串比较,匹配失败时让模式串根据next数组值向前移动
void getNext(int * next, char * needle, int len){
int i = 0, j = -1; //i记录next数组下标
next[0] = -1;
while(i < len - 1){
if(j == -1 || needle[i] == needle[j]){
i++;
j++;
next[i] = j;
}
else j = next[j]; //递归求公共前后缀
}
}
int strStr(char * haystack, char * needle){
//KMP
int i = 0, j = 0, hayLen = strlen(haystack), neeLen = strlen(needle);
if(neeLen == 0) return 0; //判断needle是否为空字符串
else if(hayLen == 0) return -1;
int *next = (int *)malloc(sizeof(int) * neeLen);
//求next数组:最长公共前后缀
getNext(next, needle, neeLen);
while(i < hayLen && j < neeLen){
if(j == -1 || haystack[i] == needle[j]){
i++; //继续对下一个字符比较
j++; //模式串向右滑动
}
else j = next[j];
}
if(j >= neeLen)
return i - j;
else return -1;
}
- C语言可以利用memcmp函数进行比较
int strStr(char * haystack, char * needle){
if(needle == NULL) return 0; //判断needle是否为空字符串
//memcmp函数比较:
int hayLen = strlen(haystack), neeLen = strlen(needle);
for(int i = 0; i <= hayLen - neeLen; i++){
if(memcmp(&haystack[i], needle, neeLen) == 0) return i;
}
return -1;
}

浙公网安备 33010602011771号