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

 更新时间:2022-07-15 03:25:37   作者:佚名   我要评论(0)

目录strstr函数介绍BF算法介绍BF算法模拟实现strstr函数KMP算法介绍KMP算法模拟实现strstr函数strstr函数介绍
C语言提供了字符串匹配函数 st

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++实现LeetCode(28.实现strStr()函数)
  • C++中strstr函数的实现方法总结
  • C 语言中strstr函数实例详解
  • 关于C语言函数strstr()的分析以及实现

相关文章

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

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

    目录strstr函数介绍BF算法介绍BF算法模拟实现strstr函数KMP算法介绍KMP算法模拟实现strstr函数strstr函数介绍 C语言提供了字符串匹配函数 st
    2022-07-15
  • vue?parseHTML?函数源码解析

    vue?parseHTML?函数源码解析

    目录正文函数开头定义的一些常量和变量while 循环textEnd ===0parseStartTag 函数解析开始标签总结:正文 接上篇: Vue编译器源码分析AST 抽
    2022-07-15
  • Python利用contextvars实现管理上下文变量

    Python利用contextvars实现管理上下文变量

    目录web 框架中的 requestThreadLocalcontextvarsc.Tokencontextvars.Context小结Python 在 3.7 的时候引入了一个模块:contextvars,从名字
    2022-07-15
  • 深入了解Java Object类的使用

    深入了解Java Object类的使用

    目录1.equals方法==运算符equals2.hashCode3.toString4.finalize1.equals方法 ==运算符 比较运算符,即可以判断基本类型又可以判断引用类型
    2022-07-13
  • 解决阿里云ECS服务器下安装MySQL无法远程连接的问题

    解决阿里云ECS服务器下安装MySQL无法远程连接的问题

    场景重现 在阿里云ECS下,Ubuntu系统上通过以下命令安装的MySQL数据库,本地连接正常, 但远程死活连接不上。 # 安装MySQL apt-get install m
    2022-07-13
  • js实现音乐播放器

    js实现音乐播放器

    本文实例为大家分享了js实现音乐播放器的具体代码,供大家参考,具体内容如下 音乐播放的主要js代码 音乐数据的数组对象 想向前端网页提供数
    2022-07-13
  • JavaScript二叉树及各种遍历算法详情

    JavaScript二叉树及各种遍历算法详情

    目录什么是二叉树满二叉树完全二叉树二叉树的存储数组存储链表存储与二叉树相关的算法深度优先遍历广度优先遍历先序遍历中序遍历后序遍历前言
    2022-07-13
  • 万字详解JavaScript手写一个Promise

    万字详解JavaScript手写一个Promise

    目录前言Promise核心原理实现Promise的使用分析MyPromise的实现在Promise中加入异步操作实现then方法的多次调用实现then的链式调用then方法链
    2022-07-13
  • JavaScript设计模式发布订阅模式

    JavaScript设计模式发布订阅模式

    目录前言发布订阅设计模式前言 发布订阅设计模式是和观察者设计模式基本上相同,但是他们两个设计模式不同的是发布订阅者拥有一个事件处理中
    2022-07-13
  • Vue中通过minio上传文件的详细步骤

    Vue中通过minio上传文件的详细步骤

    目录1、minio的安装2、minio.js文件2.1连接minio2.2通过stream流上传2.3通过带预签名的url上传(最好是minio设置了链接永久访问)2.4删除对象
    2022-07-13

最新评论