C++中strstr函数的实现方法总结

C++中strstr函数的实现方法总结

什么是strstr函数

strstr函数是C/C++中的字符串函数之一,用于在字符串中查找子串。其原型如下:

char * strstr ( const char * str1, const char * str2 );

它的功能是在 str1 字符串中查找第一次出现 str2 字符串的位置,如果未找到则返回null。

strstr函数的实现方法

以下是三种strstr函数的实现方法:

方法一:暴力匹配

暴力匹配法就是按顺序比较主串与子串的每一个字符,如果匹配成功,则继续下去;否则就从原先主串与子串匹配的下一个字符重新开始匹配。如果匹配成功,则返回第一次匹配的位置;否则返回 null。该算法的时间复杂度是O(m*n)(m为主串长度,n为子串长度),在处理较小的字符串时效率还不错,但在处理大字符串时效率很低。

char* myStrStr(const char* str1, const char* str2){
    char* cp = (char*)str1;
    char* s1, * s2;
    if (!*str2) return ((char*) str1);

    while (*cp)
    {
        s1 = cp;
        s2 = (char*) str2;
        while (*s1 && *s2 && !(*s1 - *s2)) s1++, s2++;
        if (!*s2) return cp;
        cp++;
    }
    return nullptr;
}

上述代码中,cp为主串中从当前位置开始的字符串,s1为分割后的主串,s2为要查找的子串。

方法二:KMP算法

KMP算法是一种改进的字符串匹配算法,它的核心思想是利用已知信息对下一步匹配位置进行优化,以此减少匹配次数,提高效率。在处理大点的字符串时效率很高,时间复杂度为O(n+m)(m为主串长度,n为子串长度)。

char* myStrStr(const char* str1, const char* str2){
    int len1, len2, next[10000];
    len1 = strlen(str1);
    len2 = strlen(str2);

    int index = -1;
    int i = 0, j = 0;

    if (len2 == 0) return ((char*) str1);

    next[0] = -1;
    while (i < len2)
    {
        if (j == -1 || str2[i] == str2[j])
        {
            i++;
            j++;
            next[i] = j;
        }
        else
        {
            j = next[j];
        }
    }

    i = 0, j = 0;
    while (i < len1 && j < len2)
    {
        if (j == -1 || str1[i] == str2[j])
        {
            i++;
            j++;
        }
        else
        {
            j = next[j];    
        }
    }

    if (j == len2) index = i - j;
    else return nullptr;

    return (char*) (str1 + index);
}

上述代码中,str1为主串,str2为子串,next用于存储子串匹配失败时需要跳转的位置。

方法三:Boyer Moore算法

Boyer Moore算法也是一种改进的字符串匹配算法,它的核心思想是在字符串匹配失败时,从后往前匹配,以此减少匹配次数,提高效率。该算法是实际应用中最广泛的字符串查找算法之一。

char* myStrStr(const char* str1, const char* str2)
{
    int len1 = strlen(str1);
    int len2 = strlen(str2);

    if (len2 == 0) return (char*)str1;

    int index = -1, i = len2 - 1, j = len2 - 1, pos;
    while (i < len1 && j >= 0)
    {
        while (str1[i] != str2[j] && j >= 0)
        {
            pos = myCharInStr(str2, len2, str1[i], j-1);
            if (pos == -1) i += len2;
            else i += len2 - pos - 1;
            j = len2 - 1;
        }
        i--;
        j--;
    }

    if (j == -1) index = i + 1;
    else return nullptr;

    return (char*) (str1 + index);
}

int myCharInStr(const char* str, int len, char c, int pos)
{
    for (int i = pos; i >= 0; i--)
    {
        if (str[i] == c) return i;
    }

    return -1;
}

上述代码中,str1为主串,str2为子串,pos记录在出现不匹配时,子串中下一个字符的匹配位置向后移一位。

示例

示例一

#include<cstring>
#include<iostream>

using namespace std;

char* myStrStr(const char* str1, const char* str2)
{
    int len1 = strlen(str1);
    int len2 = strlen(str2);

    if (len2 == 0) return (char*)str1;

    int index = -1, i = len2 - 1, j = len2 - 1, pos;
    while (i < len1 && j >= 0)
    {
        while (str1[i] != str2[j] && j >= 0)
        {
            pos = myCharInStr(str2, len2, str1[i], j-1);
            if (pos == -1) i += len2;
            else i += len2 - pos - 1;
            j = len2 - 1;
        }
        i--;
        j--;
    }

    if (j == -1) index = i + 1;
    else return nullptr;

    return (char*) (str1 + index);
}

int myCharInStr(const char* str, int len, char c, int pos)
{
    for (int i = pos; i >= 0; i--)
    {
        if (str[i] == c) return i;
    }

    return -1;
}

int main(){
    char a[] = "hello world";
    char b[] = "world";
    char* p = myStrStr(a,b);
    if (p)
        cout << p << endl;
    else
        cout << "not found" << endl;

    return 0;
}

在上述示例中,主串为“hello world”,子串为“world”,通过使用Boyer Moore算法查找子串在主串中的位置,输出结果为“world”。

示例二

#include<cstring>
#include<iostream>

using namespace std;

char* myStrStr(const char* str1, const char* str2)
{
    int len1, len2, next[10000];
    len1 = strlen(str1);
    len2 = strlen(str2);

    int index = -1;
    int i = 0, j = 0;

    if (len2 == 0) return ((char*) str1);

    next[0] = -1;
    while (i < len2)
    {
        if (j == -1 || str2[i] == str2[j])
        {
            i++;
            j++;
            next[i] = j;
        }
        else
        {
            j = next[j];
        }
    }

    i = 0, j = 0;
    while (i < len1 && j < len2)
    {
        if (j == -1 || str1[i] == str2[j])
        {
            i++;
            j++;
        }
        else
        {
            j = next[j];    
        }
    }

    if (j == len2) index = i - j;
    else return nullptr;

    return (char*) (str1 + index);
}

int main(){
    char a[] = "hello world";
    char b[] = "world";
    char* p = myStrStr(a,b);
    if (p)
        cout << p << endl;
    else
        cout << "not found" << endl;

    return 0;
}

在上述示例中,主串为“hello world”,子串为“world”,通过使用KMP算法查找子串在主串中的位置,输出结果为“world”。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C++中strstr函数的实现方法总结 - Python技术站

(0)
上一篇 2023年5月24日
下一篇 2023年5月24日

相关文章

  • C++中实现OpenCV图像分割与分水岭算法

    C++中实现OpenCV图像分割与分水岭算法攻略 1. 简介 图像分割是指将一幅图像分成若干个互不重叠、尽可能相似的区域,这些区域称之为图像分割区域。图像分割是图像处理、计算机视觉、模式识别等领域的一个重要问题,其应用广泛,如医学影像分析、自动驾驶、安防监控等。OpenCV是一个非常常用的计算机视觉库,提供了许多图像处理算法,其中包括了分水岭算法。 分水岭算…

    C 2023年5月22日
    00
  • 基于C语言实现的贪吃蛇游戏完整实例代码

    “基于C语言实现的贪吃蛇游戏完整实例代码”攻略 1. 总体介绍 该贪吃蛇游戏代码是基于C语言实现的经典小游戏。具体实现方式是控制某一个方向键使蛇移动,每次蛇吃到食物的时候,则身体变长,直到蛇的身体覆盖整个游戏屏幕。此过程中有各种UI,比如分数、游戏结束等。此代码使用的是Windows平台的控制台界面。 2. 代码实现步骤 2.1 游戏的设置 将控制台窗口的大…

    C 2023年5月30日
    00
  • vue-cli使用stimulsoft.reports.js的详细教程

    下面是“vue-cli使用stimulsoft.reports.js的详细教程”的完整攻略,包含两个示例: 1. 环境准备 在开始之前,需要确认电脑已经安装了以下软件: Node.js npm Vue CLI 如果没有安装,可以到官网下载安装对应版本。安装完毕后,打开命令行工具,输入以下命令进行版本确认: node -v npm -v vue –versi…

    C 2023年5月23日
    00
  • C++实现学生信息管理系统

    C++ 实现学生信息管理系统的攻略可以分为以下几个步骤: 1. 界面设计 学生信息管理系统需要一个良好的界面来提供用户友好的使用体验。可以使用如 Qt 等界面框架,或者使用C++标准库提供的基本控制台界面来实现。 2. 数据存储与处理 信息管理系统需要能够存储和处理学生信息,可以选择使用文件、数据库或者数据结构等来完成。 2.1 文件存储 使用文件存储数据是…

    C 2023年5月23日
    00
  • c语言分离三位数的实现

    C语言分离三位数的实现 问题描述 需要将一个三位数拆分成它的百位、十位、个位并分别输出。 实现思路 首先我们需要得到这个三位数的百位、十位、个位,然后分别输出即可。对于一个三位数$abc$,它的百位是$a$,十位是$b$,个位是$c$。我们可以使用除法和取余两种方式来获取这三个数字。 除法:$a = abc / 100$;$b = abc / 10 \% 1…

    C 2023年5月23日
    00
  • C语言常用库函数的使用及模拟实现详解例举

    C语言常用库函数的使用及模拟实现详解 C语言是一门非常常用的编程语言,这门语言有很多常用的库函数,这些库函数可以让我们更加方便、快速地完成代码的编写,同时,了解这些库函数的使用,也能够让我们更深刻地理解C语言的语法和特性。 常用库函数的使用 字符串操作库函数 字符串操作是C语言中最常用的操作之一,C语言提供了很多常用的字符串操作库函数,我们常用的字符串操作函…

    C 2023年5月23日
    00
  • C语言 运算符详细介绍及示例代码

    C语言 运算符详细介绍及示例代码 介绍 运算符是C语言中必不可少的部分,它们用于实现C程序中的各种运算操作。C语言共有如下几种运算符:算术运算符、关系运算符、逻辑运算符、位运算符、赋值运算符和其他运算符。在下面的攻略中,我们将对这些运算符进行详细介绍和示例说明。 算术运算符 算术运算符包括加、减、乘、除、取余和取反。它们的示例如下: int a = 10, …

    C 2023年5月23日
    00
  • 基于条件变量的消息队列 说明介绍

    基于条件变量的消息队列是一种进程间通信机制,适用于多线程环境。在使用过程中,需要注意线程同步和互斥的问题。 什么是条件变量 条件变量是线程间同步的一种方式,线程可以调用它的wait()方法将自己阻塞,直到其他线程调用signal()方法才能重新运行。条件变量常和互斥锁配合使用,锁用来保护数据,条件变量用来等待特定条件的发生。 消息队列 消息队列是一种消息传递…

    C 2023年5月22日
    00
合作推广
合作推广
分享本页
返回顶部