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日

相关文章

  • C4D怎么建模三维立体的摩天轮?

    当我们要建模三维立体的摩天轮时,通常需要经过以下步骤: 步骤一:创建摩天轮主体的外形 这个步骤可以用多边形建模实现。我们可以先创建轮廓线,然后再为其赋予一个融合体(Extrude)属性来进行外形建模。这里我们用一个圆形作为轮廓线的基础。具体步骤如下: 打开C4D,再打开新建一个工程。 将“多边形建模”界面的开关打开。(然后,将视图模式切换至左视图模式) 将圆…

    C 2023年5月22日
    00
  • C语言实现维吉尼亚密码的示例代码

    本文将介绍如何使用C语言实现维吉尼亚密码,并提供示例代码和对代码的详细解释。 什么是维吉尼亚密码? 维吉尼亚密码是一种多表替换密码,具有很高的安全性。它通过多次替换明文中的每个字符来生成密文,替换规则基于密钥和一组密文表,因此需要人工进行密钥分配和密文表的生成。由于密钥和密文表不会在通信中传输,因此维吉尼亚密码非常安全。 维吉尼亚密码的实现方式 维吉尼亚密码…

    C 2023年5月24日
    00
  • C 程序 对字符串集排序

    下面是详细讲解“C 程序 对字符串集排序”的完整使用攻略。 概述 在 C 语言中,我们可以使用 qsort() 函数对字符串集进行排序。具体来说,我们需要填写几个参数,包括要排序的字符串数组指针、字符串数组中字符串的个数、每个字符串的长度、和一个比较函数指针。比较函数指针是用来告诉 qsort() 函数如何进行排序的,这个函数会比较两个字符串,然后返回一个负…

    C 2023年5月9日
    00
  • C语言实现队列的示例详解

    C语言实现队列的示例详解 简介 队列是一种常用的数据结构,类似于排队,先进先出。C语言中可以使用结构体、数组、指针等方式来实现队列。本文将介绍如何使用数组实现队列。 实现过程 使用数组实现队列需要定义两个指针:一个指向队列头,一个指向队列尾。 1. 定义队列结构体 结构体定义如下,其中front为队列头指针,rear为队列尾指针,maxSize为队列容量,a…

    C 2023年5月23日
    00
  • C程序 两个复数相加

    C程序:两个复数相加使用攻略 什么是复数? 复数是由实部和虚部组成的数字,可以表示为 a+b*i,其中 a 为实部,b 为虚部,i 为虚数单位。 目标 本篇攻略旨在帮助大家编写一个C程序,用于计算两个复数的和。程序将要接收四个变量,分别表示两个复数的实部和虚部,计算他们的和并返回结果。 程序流程 程序的大致流程如下: 首先定义两个结构体数据类型 comple…

    C 2023年5月9日
    00
  • 详解C语言随机数设置的三种方式(保姆级教程)

    首先我们来详细讲解下“详解C语言随机数设置的三种方式(保姆级教程)”这篇文章。 详解C语言随机数设置的三种方式(保姆级教程) 一、问题背景 在开发C语言程序时,我们经常需要使用到随机数。掌握如何设置C语言随机数生成器,可以帮助我们更好地编写程序。本文就C语言随机数设置的三种方式进行详细解析,并且提供示例代码和执行结果。 二、三种方式 1. 随机数发生器初始化…

    C 2023年5月22日
    00
  • ShareSDK造成App崩溃的一个BUG原因分析以及Fix方法

    让我们一步步讲解“ShareSDK造成App崩溃的一个BUG原因分析以及Fix方法”的完整攻略。 问题背景 在使用ShareSDK进行第三方分享的时候,存在一个BUG:在Android 9.0以上的设备上,使用ShareSDK的QQ和微信分享功能会造成App崩溃。 原因分析 经过分析,导致这个BUG的原因是因为ShareSDK中使用了一个过时的API导致的。…

    C 2023年5月23日
    00
  • C语言实现商品管理系统开发

    C语言实现商品管理系统开发攻略 介绍 本文将介绍如何使用C语言开发一个简单的商品管理系统。商品管理系统是指一个管理商品库存、添加商品信息、查询商品信息、删除商品信息等简单功能的系统。 步骤 1. 设计数据结构 在编写商品管理系统之前,需要先确定系统所需的数据结构。本系统的数据结构包括商品的名称、价格、库存量等信息。可以使用结构体(struct)来存储这些信息…

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