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; }