实现strStr()

题目描述:

实现 strStr() 函数。

给你两个字符串 haystack 和 needle ,请你在 haystack 字符串中找出 needle 字符串出现的第一个位置(下标从 0 开始)。如果不存在,则返回 -1 。

说明:

当 needle 是空字符串时,我们应当返回什么值呢?这是一个在面试中很好的问题。

对于本题而言,当 needle 是空字符串时我们应当返回 0 。这与 C 语言的 strstr() 以及 Java 的 indexOf() 定义相符。

示例:

输入:haystack = "hello", needle = "ll"
输出:2
输入:haystack = "", needle = ""
输出:0
输入:haystack = "aaaaa", needle = "bba"
输出:-1

朴素模式匹配:

该题是典型的串的模式匹配问题,而数据结构中我们学到,对于串的模式匹配文题,有两种解法,分别为朴素的模式匹配和KMP模式匹配。

先讲第一种朴素模式匹配,也即暴力解法,定义两个指针i,j分别指向主串和模式串,每次比较当前两个指针指向的元素:

1)当元素相等时,i++,j++继续向后比较;

2)当元素不相等时,两指针分别回溯,i=i-j+1,j=0(注意,在这里,因为模式串需要重新一一和主串比较,所以模式串回溯到起点j=0,而为了减少比较次数,主串回溯到i-j+1即可)(课本上是ii-j+2,因为它是从下标1开始的,而C语言默认下标从0开始)

代码:

int strStr(char * haystack, char * needle){
    int len1=strlen(haystack);
    int len2=strlen(needle);
    if(len2==0)//当needle是空字符串时,返回0
    {
        return 0;
    }
    if(len2>len1)//needle串必须小于haystack串
    {
        return -1;
    }
    int i=0;
    int j=0;
    int pos=-1;
    while(i<len1 && j<len2)
    {
        if(haystack[i]==needle[j])
        {
            i++;
            j++;
        }
        else//不匹配,主串指针i和模式串指针j分别回溯
        {
           i=i-j+1;
           j=0;
        }
        
    }
    if(j==len2)
    {
        pos=i-len2;//匹配成功,返回needle串在主串的首位置
    }
    return pos;   
}

KMP算法:

原理看这里:(27条消息) 408复习笔记——数据结构(四):串和模式匹配算法(KMP)_薪哥,很潇洒的博客-CSDN博客_408kmp代码考吗icon-default.png?t=M0H8https://blog.csdn.net/qq_44161734/article/details/118252280

代码:

int strStr(char * haystack, char * needle){
    int len1=strlen(haystack);
    int len2=strlen(needle);
    if(len2==0)//当needle是空字符串时,返回0
    {
        return 0;
    }
    if(len2>len1)//needle串必须小于haystack串
    {
        return -1;
    }
    int *next=(int *)malloc(sizeof(int)*len2);//next数组 表示当模式串和主串不匹配时跳转位置
    //构建next数组
    next[0]=0;
    for(int i=1,j=0;i<len2;i++)
    {
        while(j>0 && needle[i]!=needle[j])
        {
            j=next[j-1];
        }
        if(needle[i]==needle[j])
        {
            j++;
        }
        next[i]=j;
    }
    //kmp模式匹配
    int j=0;
    for(int i=0;i<len1;i++)
    {
        while(j>0 && haystack[i]!=needle[j])
        {
            j=next[j-1];
        }
        if(haystack[i]==needle[j]) 
        {
           j++; 
        }
        if(j==len2)
        {
            return i-j+1;
        }
    }
    return -1;
    
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值