C语言模拟实现strstr函数的示例代码

 更新时间:2022年07月13日 16:34:29   作者:Liquor999  
strstr是C语言中的函数,作用是返回字符串中首次出现子串的地址。本文将用C语言模拟实现strstr函数,感兴趣的小伙伴可以跟随小编一起学习一下

strstr函数介绍

C语言提供了字符串匹配函数 strstr 函数,请看文档简介。

这个函数是用来匹配 str2 是否包含在 str1 字符串中,如果匹配成功,则返回指向str1中第一个出现的str2的指针,如果str2不是str1的一部分,则返回空指针。
我们不妨举例说明,请看下面代码,调用 strstr 函数需要引入string.h头文件,我们发现,s1字符串中可以找到s2字符串,那么就返回s1中s2的第一个字符的地址,s1字符串并没有s3,所以返回空指针。

#include<stdio.h>
#include<string.h>

int main(){

    char* s1 = "abcdefgh";
    char* s2 = "def";
    char* s3 = "dee";
    
    printf("%s\n",strstr(s1,s2)); //defgh   
    printf("%s\n",strstr(s1,s3)); //(null)

    return 0;
}

BF算法介绍

BF算法,即暴力(Brute Force)算法,BF算法的思想就是str1的第一个字符与str2的第一个字符进行匹配,若相等,则继续比较str1的第二个字符和 str2的第二个字符;若不相等,则比较str1的第二个字符和str2的第一个字符,依次比较下去,直到得出最后的匹配结果。

BF算法模拟实现strstr函数

用BF算法实现 strstr 函数的思路就是遍历整个 str1,在内层循环进行判断,如果str1 和 str2 对应的字符相等且比较的字符在 str2 长度范围之内, 那么就比较下一位,当这次循环结束,此时只有两种情况,第一种是比较的字符等于 str2 的长度,那么就代表找到了,返回 str2 在 str1 第一个字符地址即可,至于为什么是 str1 + i - j,请朋友们思考一下就明白了。第二种情况是某个字符之间不匹配,那么 str1 下次匹配的位置为前一个字符位置 + 1,str2 又回到第一个字符开始匹配。直到整个 str1 超出了匹配的范围,代表找不到整个字符串 str2,故返回NULL。

char* my_strstr(char* str1, char* str2){
    assert(str1 && str2);
    
    int slen = strlen(str1);
    int sublen = strlen(str2);
    
    int i = 0;
    int j = 0;
    int count = 0;

    while(i < slen){
        
        while(str1[i] == str2[j] &&  j < sublen){
            ++i;
            ++j;
        }

        if(j >= sublen){
            return str1 + i - j;
        }
        
        ++count;
        i = count;
        j = 0;
        
    }        

    return NULL;

}

KMP算法介绍

KMP算法是一种改进的字符串匹配算法,由D.E.Knuth,J.H.Morris和V.R.Pratt提出的,因此人们称它为克努特—莫里斯—普拉特操作(简称KMP算法)。KMP算法的核心是利用匹配失败后的信息,尽量减少模式串(str2)与主串(str1)的匹配次数以达到快速匹配的目的。具体实现就是通过一个next数组实现,数组本身包含了模式串的局部匹配信息。

KMP算法与BF算法的区别是:主串不会回退,模式串每次也不一定回退到第一个位置上。

具体算法思想可参考:KMP算法讲解

KMP算法模拟实现strstr函数

#include<stdio.h>
#include<string.h>
#include<assert.h>
#include<stdlib.h>

void get_next(int* next, char* sub){
    int len = strlen(sub);
    next[0] = -1;
    next[1] = 0;

    int i = 2;
    int k = 0;

    while(i < len){
        if(k == -1 || sub[i-1] == sub[k]){
            next[i] = ++k;
            ++i;
        }else{
            k = next[k];
        }
    }
    
    
    
}

char* my_strstr(char *str1, char * str2){
    assert(str1 && str2);
    
    int slen = strlen(str1);
    int sublen = strlen(str2);

    int* next = (int*)malloc(sizeof(int)*sublen);
    assert(next);
    get_next(next,str2);

    int i = 0;
    int j = 0;

    while(i < slen && j < sublen){
        if(j == -1 || str1[i] == str2[j]){
            ++i;
            ++j;
        }else{
            j = next[j];
        }
    }

    if(i >= sublen){
        return str1 + i - j;
    }else{
        return NULL;
    }
    
}

到此这篇关于C语言模拟实现strstr函数的示例代码的文章就介绍到这了,更多相关C语言 strstr函数内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • C++ 继承的范例讲解

    C++ 继承的范例讲解

    继承是C++面向对象编程中的一门。继承是子类继承父类的特征和行为,或者是继承父类得方法,使的子类具有父类得的特性和行为。重写是子类对父类的允许访问的方法实行的过程进行重新编写,返回值和形参都不能改变。就是对原本的父类进行重新编写,但是外部接口不能被重写
    2022-06-06
  • 利用C++编写一个Json解析器

    利用C++编写一个Json解析器

    这篇文章主要为大家详细介绍了如何利用C++编写一个简单又好用的Json解析器,文中的示例代码讲解详细,感兴趣的小伙伴可以了解一下
    2023-03-03
  • C/C++使用过程中的溢出问题详解

    C/C++使用过程中的溢出问题详解

    在C/C++程序里有一类非常典型的问题,那就是:溢出问题,现在分别来分析一下常见的数组溢出,整数溢出,缓冲区溢出,栈溢出和指针溢出等,需要的朋友可以参考下
    2024-01-01
  • C++指针作为函数的参数进行传递时需要注意的一些问题

    C++指针作为函数的参数进行传递时需要注意的一些问题

    当指针作为函数的参数进行传递的时候,本质上还是进行的“值传递”,也就是复制了一个新的指向该地址的指针变量
    2013-10-10
  • C++连接mysql的方法(直接调用C-API)

    C++连接mysql的方法(直接调用C-API)

    首先安装mysql,点完全安装,才能在在安装目录include找到相应的头文件,注意,是完全安装,需要的朋友可以参考下
    2017-06-06
  • C语言修炼之路函数篇真题训练下

    C语言修炼之路函数篇真题训练下

    函数是一组一起执行一个任务的语句。每个 C 程序都至少有一个函数,即主函数 main() ,所有简单的程序都可以定义其他额外的函数
    2022-03-03
  • C语言实现双人反弹球游戏

    C语言实现双人反弹球游戏

    这篇文章主要为大家详细介绍了C语言实现双人反弹球游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-05-05
  • 数组名不等于指针 sizeof()函数求数组大小错误问题及解决

    数组名不等于指针 sizeof()函数求数组大小错误问题及解决

    这篇文章主要介绍了数组名不等于指针 sizeof()函数求数组大小错误问题及解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-11-11
  • C++实现LeetCode(46.全排列)

    C++实现LeetCode(46.全排列)

    这篇文章主要介绍了C++实现LeetCode(46.全排列),本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-07-07
  • 关于C/C++中的side effect(负效应)和sequence point(序列点)

    关于C/C++中的side effect(负效应)和sequence point(序列点)

    不知你在写code时是否遇到这样的问题?int i = 3; int x = (++i) + (++i) + (++i); 问x值为多少?进行各种理论分析,并在编译器上实践,然而可能发现最终的结果是不正确的,也是不稳定的,不同的编译器可能会产生不同的结果。这让人很头疼
    2013-10-10

最新评论