字符串函数剖析(3)---strstr函数

news2024/11/18 13:44:28

1.strstr函数的巧妙 – 查找子字符串

1.1模拟实现strstr函数

strstr函数:在一个字符串中查找子串

学习新函数时,先去c库查找该函数的相关资料,更加助于你的学习

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

先看函数的声明,
参数是两个地址,不可更改。
先看看strstr函数的用法:
假如有一个字符串p1 = “abcdef” ,另一个字符串 p2 =“cde”,在p1中查找p2,肉眼可见,p1中确实存在p2,用代码来展示一下:

int main()
{
	char p1[] = "abcdef"
	char p2[] = "cde";
	char *ret = strstr(p1, p2);
	if (ret == NULL)
	{
		printf("%s\n", "找不到");
	}
	else
	{
		printf("%s\n", ret);
	}
}

在这里插入图片描述
可以看到,打印出了cdef,来看一下库函数的解释:
在这里插入图片描述
它的意思是,如果字符串1中不存在字符串2,则返回 NULL,否则,返回字符串1中出现字符串2的首次出现的地址。在上面 “abcdef” 和 "cde"的例子中,返回值则为c的地址,打印出来的话,就会顺着c的地址往下打印。

那假如 是这样的例子呢?
p1 = “abcdebcde” , p2 = “cde”,

在这里插入图片描述
很明显,由库函数的返回值可知,返回的是第一次出现这个串时的地址。

下面来模拟实现my_strstr函数:

模拟实现strstr函数

在模拟实现该函数之前,我们先看一个例子,看懂这个例子,你才能看懂模拟实现的过程。

假设有一字符串:p1 = “abbbcde” , p2 = “bbc”,则在 p1 中查找 p2,很明显,肉眼可以知道,的确存在。
当我们去写代码时:,先看下图:

在这里插入图片描述
,p1 所指向的位置!= p2,所以 p1 后移一位,移动到b,此时 p1 == p2,继续后移,直到p2 指向c,p1 指向第三个b时,
在这里插入图片描述
此时p1 != p2,则需要将p2回溯到最开始的位置p1也从最开始的位置的后一位开始查找,如下图:

在这里插入图片描述
但遗憾的是,没人记住p1 和 p2的最开始的位置,p1 和p2 一旦移动了,就不好找回原来的位置了,所以定义两个临时变量指向 p1和p2的位置,
在这里插入图片描述
此时我们只需要移动s1和s2即可,p1和p2保持不变,回到刚刚上面的那句加粗的话:
p2回溯到最开始的位置p1也从最开始的位置的后一位开始查找,这个任务就交给s1和s2来做就行,我们继续往下走:此时s1与s2所指向的第一个和第二个位置都匹配了,但是当s2指向c,s1指向第三个b时,不相同,则 s2 又回溯到p2 的位置,s1回溯到p1的 后两位,这里又出现了一个问题, p1一动不动在a这个位置,怎么知道p1的后两位是哪一个字母呢?,这又需要引入另一个变量 :cur
在这里插入图片描述
当我们的s1每次回溯时,cur都会往下走一位,说明没有匹配到子串。
这是p1 在每次移动时的过程:在这里插入图片描述
在这里插入图片描述
这是p2在每次移动时的过程

当每一次匹配不成功时,cur会跳转到下一位,继续匹配
看到这里,如果你明白了,那就大功告成了。

char* my_strstr(const char* p1, const char* p2)
{
	assert(p1 && p2);
	char* s1 = NULL;
	char* s2 = NULL;
	char* cur = (char*)p1; NUL和Null都是 '\0'
	if (*p2 == '\0')
	{
		return (char*)p1;
	}
	while (*cur)
	{                 abbbcdef
		              bbc
		s1 = cur;
		s2 = (char*)p2;
		while (s1 && s2 && (*s1 == *s2))
		{
			s1++;
			s2++;
		}
		if (*s2 == '\0')
		{
			return cur; //找到了
		}
		if (*s1 == '\0')
		{
			return NULL;//找不到
		} 相当于找完了p1串都找不到,跳出cur的循环,这里如果多写一层,就画蛇添足了
		cur++;
	}
	return NULL; 找完了p1都找不到

}

重点部分再次详细介绍。
在这里插入图片描述
结果如上:
总结:重点是理解 ”abbbcdef“ 和”bbc“这个例子就大功告成了在这里插入图片描述

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

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

相关文章

测开工具:spring boot 实现同步数据库表结构(持续更新)

一、使用场景 一个项目,有多套开发环境。有一套标准的数据库,不同的开发环境,有各自的一套数据库。 标准数据库的表结构经常发生变化,不同的开发环境中的数据库,需要与标准数据库的表结构保持一致。当标准数据库表结…

HNU编译原理实验一cminus_compiler-2022-fall

前言:实验不是很难,主要考察正则表达式部分 lab1实验报告实验要求 根据cminux-f的词法补全lexical_analyer.l文件,完成词法分析器,能够输出识别出的token,type ,line(刚出现的行数),pos_start(该行开始位置…

[机缘参悟-95] :不同人生、社会问题的本质

事情的本质是物极必反(轮回、周期) 社会的本质是优胜劣汰(迭代、发展) 道德的本质是伦理秩序(未定、秩序) 战争的本质是资源占用(弱肉、强食) 商业的本质是价值交换 金钱的本质…

基于JAVA SpringBoot+ JWT+Redis的ERP系统,VUE+Element-UI 前后端分离的Saas平台

项目简介 简云Saas平台 基于SpringBoot2.2.0, Mybatis, JWT, Redis, VUEElement-UI 的前后端分离的Saas平台管理系统 在线报表开发 在线表单设计 工作流设计 自定义打印模板定义 **产品分二个版本: 开源版本(包含了系统基础架构在线表单设计). 此版本代码完全开源ERP版本…

Flink-基本的合流操作

文章目录1.基本的合流操作2.1联合(Union)2.2 连接(Connect)2.基于时间的合流——双流联结(Join)2.1 窗口联结(Window Join)2.2 间隔联结(Interval Join)2.3 窗…

《面向对象分析与设计》总结

面向对象的软件工程1 面向对象的演化1.1 生活中复杂系统的特点1.2 软件系统的复杂性1.2.1 复杂性的四个方面1.2.1.1 问题域的复杂性1.2.1.2 管理开发的困难性1.2.1.3 软件中的灵活性1.2.1.4 描述离散系统行为1.2.2 复杂系统的五个属性1.2.2.1 层次结构1.2.2.1.1 对象结构1.2.2.…

数据分析神器:数据自动录入并生成BI报表

做报表、分析数据、做汇报是许多打工人的日常,每天都要耗费不少的时间用Excel来整理、清洗数据和生成好看的报表。如果这些数据都是手动整理、复制粘贴的话,不仅费时费力,而且很容易出错。 在越来越多企业采用SaaS产品和不同数据应用的今天&…

来看一个vue-element-表单之登录页面,最后送上一个登录页面

vue-element 表单之登录页面使用 0. 先留下属性表格 表单验证:Form 组件提供了表单验证的功能,只需要通过 rules 属性传入约定的验证规则,并将 Form-Item 的 prop 属性设置为需校验的字段名即可。 1. 表单属性表(el-form) 2. 表单项属性表…

php工作流引擎再发新版本—Tpflow7.0重磅发布

2022年已接近尾声,又到了每年发布大版本的时候,Tpflow历经一个多月的意见征集及版本优化,从底层改进,从UI调整,增强了事件功能。 发布日期:2022年12月23日 发布版号:V7.0.0 Tpflow 工作流引擎…

短视频引流+私域流量沉淀,一个全新的短视频和链动模式结合方案

在微盟企微助手微盟智慧零售团队的协助下,今年7月底么么茶正式开始运营企微私域,截至当前,在短短3个月时间已成功沉淀7万私域客户,线上商城GMV超145万。 么么茶旅拍的核心流量来源自公域短视频平台,品牌基于服务覆盖下…

OB0206 obsidian 表格编辑插件:advanced Tables插件使用

序号解读: 01——软件基础使用、基础语法 02——插件使用 03——综合实战 0 写在前面 Ob社区插件汇总:Airtable - OB社区插件汇总 - Johnny整理 - 每周更新 - B站 Johnny学Explore the "OB社区插件汇总 - Johnny整理 - 每周更新 - B站 Johnny学&qu…

执行操作后的变量值,我的题解首次优于官方

2011. 执行操作后的变量值 难度简单46 存在一种仅支持 4 种操作和 1 个变量 X 的编程语言: X 和 X 使变量 X 的值 加 1--X 和 X-- 使变量 X 的值 减 1 最初,X 的值是 0 给你一个字符串数组 operations ,这是由操作组成的一个列表&#xf…

求N阶矩阵的幂(一维,二维多种方法)

引用:对于矩阵的计算想必都是一件很头疼的事情吧,因为计算量是比较大,因为你要用前一个矩阵的行乘以后矩阵的列且对应相加才得到新矩阵的第一个元素,且两个矩阵可以相乘的条件也是前一个矩阵的列等于后一个矩阵的行,操…

Simulink代码生成: Switch模块及其代码

本文描述Switch模块的建模并研究生成的代码。 文章目录1 Simulink中的Switch模块2 Switch模块建模及代码生成3 Switch模块其他用法3.1 多重Switch3.2 通过标定量Switch4 总结1 Simulink中的Switch模块 在Simulink中Switch模块时非常常见的,通常用于根据一定地条件选…

Python学习笔记(十九)——Matplotlib入门上

目录 Matplotlib简介 导入matplotlib模块 图的参数说明 matplotlib图像组成部分介绍 matplotlib绘图步骤分析 matplotlib实现简单图像 matplotlib画布 画布-plt.figure() 实例 同一画布制作多张图像 创建多个子图 实例 plt.subplots 相关参数 调整subplot周围的间距…

使用HGS算法调整PD控制器增益的无人机动态性能数据——基于启发式的无人机路径跟踪优化(Matlab代码实现)

👨‍🎓个人主页:研学社的博客 💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜…

【Sentinel 预热加载】

系列文章目录 Sentinel 预热加载 目录 系列文章目录 前言 一、概念解释? 二、使用步骤 1.引入库 2.dashboard 配置 总结 前言 一、概念解释? Warm Up:根据coldFactor(冷加载因子,默认3)的值,从…

有了 HTTP,为什么还要 RPC?

RPC主要是基于TCP/IP协议的,而HTTP服务主要是基于HTTP协议的,我们都知道HTTP协议是在传输层协议TCP之上的,所以效率来看的话,RPC当然是要更胜一筹啦!下面来具体说一说RPC服务和HTTP服务。 OSI网络七层模型 在说RPC和…

Android HIDL和hwservicemanager

HIDL软件包 HIDL 接口软件包位于 hardware/interfaces 或 vendor/ 目录下(个别情况除外)。顶层 hardware/interfaces 会直接映射到 android.hardware 软件包命名空间;版本是软件包(而不是接口)命名空间下的子目录。 h…

ALPHA项目的测试电机、性能信息和动态推力近似值数据库(Matlab代码实现)

目录 💥1 概述 📚2 运行结果 🎉3 参考文献 👨‍💻4 Matlab代码 💥1 概述 按照电机试验的完整性,可以将电机试验分为型式试验、单项目或部分项目试验等;其中型式试验包括产品的性…