Leetcode28. 实现 strStr()(C语言)

Leetcode28. 实现 strStr()(C语言)

题目:
实现 strStr() 函数。
给定一个 haystack 字符串和一个 needle 字符串,在 haystack 字符串中找出 needle 字符串出现的第一个位置 (从0开始)。如果不存在,则返回 -1。例:
输入: haystack = “hello”, needle = “ll”
输出: 2

思路:
kmp算法。分为文本串与模式串,先构造临时数组存储模式串前后缀匹配情况;再用临时数组用模式串依次与文本串匹配。
避免暴力法中每次遇到不匹配时从头匹配

阿三哥讲的超清晰的kmp算法

代码:

void kmp_init(const char *s, int *tmp, int size) { //临时数组存储字串前后缀匹配情况
    tmp[0] = 0;
    for (int i = 1; i < size; i++) {
        if (s[i] == s[tmp[i - 1]])    tmp[i] = tmp[i - 1] + 1;
        else {
            int j = i - 1;
            while (tmp[j] > 0 && s[tmp[j]] != s[i])   j = tmp[j] - 1;   //找到上一个出现s[i]的位置

            if (tmp[j] > 0)   tmp[i] = tmp[j] + 1;  //从上一次出现位置为起始,开始匹配
            else    tmp[i] = (s[i] == s[0]);        //从tmp0开始匹配,不匹配为0
        }
    }
}

int strStr(const char *src, const char *dest) {
    if (!dest || !src)  return -1;
    if (!*dest) return 0;

    int size = strlen(dest);
    int *tmp = malloc(sizeof(int) * size);
    kmp_init(dest, tmp, size);

    int i, j;
    for (i = j = 0; src[i] && j < size; i++) {  //每次文本串指针均后移
        if (dest[j] == src[i])    j++;          //匹配,模式串指针后移
        else if (j) {   //至少一个匹配
            while (tmp[j - 1] > 0 && dest[tmp[j - 1]] != src[i])    j = tmp[j - 1];     //模式串定位到上一个匹配位置

            if (tmp[j - 1] > 0)    j = tmp[j - 1] + 1;        //模式串定位到匹配位置(不为起始位置)
            else    j = (dest[0] == src[i]);       //模式串从头和src[i]比较,若不同,下一循环仍从头比较
        }
    }

    free(tmp);
    if (j < size)   return -1;  //模式串不能完全匹配
    return i - size;    //返回第一次出现位置
}
//参考评论区@swhc

你可能感兴趣的:(数据结构&算法)