strstr 的使用和模拟实现

news2024/9/24 17:13:15

就位了吗?如果坐好了的话,那么我就要开始这一期的表演了哦!

strstr 的使用和模拟实现:

char * strstr ( const char * str1, const char * str2);
Returns a pointer to the first occurrence of str2 in str1, or a null pointer if str2 is not part of str1. (函数返回字符串str2在字符串str1中第⼀次出现的位置)。
The matching process does not include the terminating null-characters, but it stops there.(字符 串的⽐较匹配不包含 \0 字符,以 \0 作为结束标志)。

strstr 的使用:

这些函数的使用呢都是非常简单的,我们只需要加上相应的头文件就可以了。

函数返回字符串str2在字符串str1中第⼀次出现的位置 !

strstr 的模拟实现:

那么对于strstr函数的模拟实现,我们应该怎么做呢?我们一起来画图分析分析:

 我们用i和j指向的位置进行比较:

首先我们的a和b不相等,那么我们的i需要向后移一位,指向了我们的b,我们的j没有动。

现在b和b相等,那么此时我们的i和j都需要向后移一位进行比较,还是相等的,继续向后移动一位,此时我们的主串为c,子串为我们的d,两者不相等。那么我们此时我们的主串的i是不是应该返回到我们下标为2的位置进行重新下一步比较呢。我们的子串则返回到下标为0的位置重新比较!j可以很好的返回到我们的0的位置,那么我们的i又该怎样计算呢?在最开始的时候我们的首元素不相等,我们的主串的i向后移动了一步,然后相等后一起向后加加,所以我们可以很好的推导出:i = i-j+1!

此时主串的i移动到下表为2的位置时与子串的不相等,此时我们的就需要向后移动位置了,i= 2-0+1 = 3;还是不相等,继续向后移动一位。此时主串i的位置与我们子串的元素相等,那么此时i和j一起向后移动一位,还是相等的我们接着移动一位,还是相等的!那么我们就继续向后移动一位,此时我们的子串的元素与我们主串的元素不相等,但是此时我们子串所指向的元素为\0,说明此时我们已经历遍完我们子串了,那么说明在主串中找到了子串,那么此时我们的i就应该返回到我们下标为4的位置!此时如果我们再以i = i-j+1进行计算的话,就是我们下标为5的位置,是错误的。所以此时我们应该写成i= i-j,因为它们俩是一起移动的。所以我们的大体思路都知道了,下面我们一起来看看代码的实现:

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <string.h>
#include <assert.h>

int BFalg(const char* str1,const char* str2)
{
	assert(str1 && str2);//先进行断言一下
	if (str1 == NULL || str2 == NULL)
	{
		return -1;//如果为空指针,找不到我们就返回-1
	}
	size_t len1 = strlen(str1);
	size_t len2 = strlen(str2);

	int i = 0;
	int j = 0;

	while (i < len1 && j < len2)
	{
		if (str1[i] == str2[j])
		{
			i++;
			j++;
		}
		else//不相等时
		{
			i = i - j + 1;
			j = 0;
		}
	}
	if (j >= len2)//历遍完时
	{
		return i - j;
	}
	return -1;
}
int main()
{
	printf("%d\n", BFalg("abcdabf", "da"));
	printf("%d\n", BFalg("abcdabf", "ba"));
	printf("%d\n", BFalg("abcdabf", "bc"));

	return 0;
}

我们来看看我们的结果是否正确: 

那么也是正确的!有了上面的推演,我们下面来看看另一种写法,方法都是一样的:我们如果不知道如何推导i退回位置的话,我们就可以拿一个变量(sr)来存储i最初出去的位置,当我们的i指向的位置不相等时 ,我们的sr就向后移动一位,然后我们的i就移动到我们sr的位置,此时我们就很好的解决了i回退的位置了!

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <string.h>
#include <assert.h>

char* BFalg(const char* str1, const char* str2)
{
	const char* sr = str1;
	const char* s1 = NULL;
	const char* s2 = NULL;

	assert(str1 && str2);
	if (*str2 == '\0')
	{
		return (char*)str1;
	}
	while (*sr)
	{
		s1 = sr;
		s2 = str2;
		while (*s1 && *s2 && *s1 == *s2)
		{
			s1++;
			s2++;
		}
		if (*s2 == '\0')
		{
			return (char*)sr;
		}
		sr++;
	}
	return NULL;
}

int main()
{
	char arr1[] = "abcdacdf";
	char arr2[] = "cd";
	char* ret = BFalg(arr1, arr2);
	if (ret != NULL)
		printf("%s\n", ret);
	else
		printf("找不到\n");

	return 0;
}

该方法呢就比较暴力了,需要我们一个一个的跳回去比较,当然还有另外的一种KMP算法,但是呢我还没有研究透,就不能向大家展示了,小伙伴们如果感兴趣的话,可以去查看资料哦!

好了,今天就到此结束了,我们下一期再见!创作不易,麻烦给一个免费的小爱心哦,♥️♥️♥️ 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1272207.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

030 - STM32学习笔记 - ADC(四) 独立模式多通道DMA采集

030 - STM32学习笔记 - ADC&#xff08;四&#xff09; 独立模式多通道DMA采集 中断模式和DMA模式进行单通道模拟量采集&#xff0c;这节继续学习独立模式多通道DMA采集&#xff0c;使用到的引脚有之前使用的PC3&#xff08;电位器&#xff09;&#xff0c;PA4&#xff08;光敏…

Peter算法小课堂—高精度乘法

给大家看个小视频13 高精度算法 乘法_哔哩哔哩_bilibili 乘法竖式 大家觉得Plan A好&#xff0c;还是Plan B好呢&#xff08;对于计算机来说&#xff09;&#xff1f;那显然是B啦 x*y问题 mul思路&#xff1a;mul()函数返回x数组乘y数组的积&#xff0c;保存在z数组。根据上…

基于SpringBoot的旅游网站的设计与实现

摘 要 随着科学技术的飞速发展&#xff0c;各行各业都在努力与现代先进技术接轨&#xff0c;通过科技手段提高自身的优势&#xff0c;旅游网站当然也不能排除在外&#xff0c;随着旅游网站的不断成熟&#xff0c;它彻底改变了过去传统的旅游网站方式&#xff0c;不仅使旅游管理…

three.js结合vue

作者&#xff1a;baekpcyyy&#x1f41f; 1.搭建环境 ps&#xff1a;这里要按照node.js在之前有关vue搭建中有介绍 新建文件夹并在vsc终端中打开 1.输入vite创建指令 npm init vitelatest然后我们cd进入刚才创建的目录下 npm install安装所需依赖 npm run dev启动该项目 …

Python正则表达式:match()和search()函数全面解读

更多资料获取 &#x1f4da; 个人网站&#xff1a;ipengtao.com 在Python中&#xff0c;正则表达式是强大的工具&#xff0c;能够用于文本匹配、搜索和替换。re模块提供了许多函数来处理正则表达式&#xff0c;其中match()和search()是两个常用的函数。本文将深入探讨这两个函…

论文复现代码《基于自适应哈夫曼编码的密文可逆信息隐藏算法》调试版

前言 本文展示论文《基于自适应哈夫曼编码的密文可逆信息隐藏算法》的复现代码。代码块的结构如下&#xff1a; 其中&#xff0c;每个代码块都包含了测试该代码块的功能的主函数代码&#xff0c;使用时可放心运行&#xff0c;前提是你按照这个包结构把文件命名改好&#xff0c…

vue3 keep-alive页面切换报错:parentComponent.ctx.deactivate is not a function

问题&#xff1a; <router-view v-slot"{ Component }"><keep-alive ><component :is"Component" v-if"$route.meta.keepAlive" /></keep-alive><component :is"Component" v-if"!$route.meta.keepA…

【软件测试】白盒测试和黑盒测试

一、软件测试基本分类 一般地&#xff0c;我们将软件测试活动分为以下几类&#xff1a;黑盒测试、白盒测试、静态测试、动态测试、手动测试、自动测试等等。 黑盒测试 黑盒测试又叫功能测试、数据驱动测试或给予需求规格说明书的功能测试。这种测试注重于测试软件的功能性需…

java二十章多线程

概念 有很多工作是可以同时完成的&#xff0c;这种思想放在Java中被称为并发&#xff0c;并发完成每一件事被称为线程。 程序员可以在程序中执行多个线程&#xff0c;每一个线程完成一个功能//与其他线程并发执行&#xff0c;这种机制被称为多线程&#xff0c;并不算所有编程…

PLC:200smart(13-16章)

PLC&#xff1a;200smart 第十三章2、带参子程序3、将子程序设置成库文件 第十三章 项目ValueValue主程序MAIN一个项目只能有一个&#xff0c;循环扫描子程序SBR_0项目中最多有128个&#xff0c;只有在调用时 才执行&#xff08;子程序可以嵌套其他子程序&#xff0c;最多八层…

广州华锐视点:基于VR元宇宙技术开展法律法规常识在线教学,打破地域和时间限制

随着科技的飞速发展&#xff0c;人类社会正逐渐迈向一个全新的时代——元宇宙。元宇宙是一个虚拟的、数字化的世界&#xff0c;它将现实世界与数字世界紧密相连&#xff0c;为人们提供了一个全新的交流、学习和娱乐平台。在这个充满无限可能的元宇宙中&#xff0c;法律知识同样…

构建个人代理池:使用GitHub项目proxy_pool的搭建配置及代码接口详解

手把手教你搭建代理IP池&#xff1a; 项目简介&#xff1a; ​ 爬虫代理IP池项目,主要功能为定时采集网上发布的免费代理验证入库&#xff0c;定时验证入库的代理保证代理的可用性&#xff0c;提供API和CLI两种使用方式。同时你也可以扩展代理源以增加代理池IP的质量和数量。…

分治法之归并排序

思路: 将待排序数组分成两个子数组&#xff0c;计算中间位置mid。对左半部分进行递归排序&#xff0c;得到一个有序的子数组。对右半部分进行递归排序&#xff0c;得到另一个有序的子数组。合并两个有序的子数组&#xff0c;得到一个完整的有序数组。 示例图: 代码: #include&…

WPF绘制进度条(弧形,圆形,异形)

前言 WPF里面圆形进度条实现还比较麻烦,主要涉及到的就是动态绘制进度条的进度需要用到简单的数学算法。其实原理比较简单,我们需要的是话两条重叠的弧线,里面的弧线要比里面的弧线要宽,这样简单的雏形就出来了。 基础写法 我们可以用Path来绘制弧线,代码如下: <Gr…

Linux:服务器管理工具宝塔(bt)安装教程

一、简介 bt宝塔Linux面板是提升运维效率的服务器管理软件&#xff0c;支持一键LAMP/LNMP/集群/监控/网站/FTP/数据库/JAVA等多项服务的管理功能 二、安装 使用 SSH 连接工具&#xff0c;如堡塔SSH终端连接到您的 Linux 服务器后&#xff0c;挂载磁盘&#xff0c;根据系统执…

C++基础——文件操作

文章目录 1 概述2 文本文件2.1 写文件2.1.1 写文件流程2.1.2 文件打开方式 2.2 读文件 3 二进制文件3.1 写文件3.2 读文件 1 概述 程序最基本的操作之一就是文件操作&#xff0c;程序运行时的数据都是临时数据&#xff0c;当程序结束后就不复存在了。通常都是通过文件或其他持…

酷狗音乐app 评论signature

文章目录 声明目标加密参数定位翻页逻辑代码实现 声明 本文章中所有内容仅供学习交流&#xff0c;严禁用于商业用途和非法用途&#xff0c;否则由此产生的一切后果均与作者无关&#xff0c;若有侵权&#xff0c;请私信我立即删除&#xff01; 目标 复制curl转python # -*- c…

SQL 数据操作技巧:SELECT INTO、INSERT INTO SELECT 和 CASE 语句详解

SQL SELECT INTO 语句 SELECT INTO 语句将数据从一个表复制到一个新表中。 SELECT INTO 语法 将所有列复制到新表中&#xff1a; SELECT * INTO newtable [IN externaldb] FROM oldtable WHERE condition;只复制一些列到新表中&#xff1a; SELECT column1, column2, colu…

MySQL三大日志详细总结(redo log undo log binlog)

MySQL日志 包括事务日志&#xff08;redolog undolog&#xff09;慢查询日志&#xff0c;通用查询日志&#xff0c;二进制日志&#xff08;binlog&#xff09; 最为重要的就是binlog&#xff08;归档日志&#xff09;事务日志redolog&#xff08;重做日志&#xff09;undolog…

数据结构(超详细讲解!!)第二十六节 图(上)

1.基本概念 图&#xff08;Graph&#xff09;是一种较线性表和树更为复杂的非线性结构。是对结点的前趋和后继个数不加限制的数据结构&#xff0c;用来描述元素之间“多对多”的关系(即结点之间的关系是任意的)。 一个图G &#xff08;V&#xff0c;E&#xff09;由顶点&…