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

  

原文地址:https://www.cnblogs.com/JesseyWang/p/12972057.html