北邮22信通:利用BF算法解决实际问题:题目实战(超详解)设计函数 char *locatesubstr(char *str1,char *str2)

北邮22信通一枚~   

跟随课程进度每周更新数据结构与算法的代码和文章 

持续关注作者  解锁更多邮苑信通专属代码~

获取更多文章  请访问专栏~

北邮22信通_青山如墨雨如画的博客-CSDN博客

目录

题干描述 

解析

1.string库函数

2.使用KMP算法思想

注解1

注解2

注解3


题干描述 

 设计函数 char *locatesubstr(char *str1,char *str2),查找str2指向的字符串在str1指向的字符串中首次出现的位置,返回指向该位置的指针。若str2指向的字符串不包含在str1指向的字符串中,则返回空指针NULL。

注意这里必须使用指针而不是数组下标来访问字符串。

函数接口定义:\n\nchar *locatesubstr(char *str1,char *str2);

其中 str1 和 str2 都是用户传入的参数,其含义如题面所述 。若查找成功则返回指向该位置的指针,若失败则返回空指针。

裁判测试程序样例:

#include <iostream>
using namespace std;
char* locatesubstr(char* str1, char* str2);
int main()
{
    char str1[505], str2[505];
    char* p;
    gets(str1);
    gets(str2);
    p = locatesubstr(str1, str2);
    if (p == NULL) 
        printf("NULL!\n");
    else puts(p);
    return 0;

}

输入样例:

didjfsd dabcxxxxxx

abc

输出样例:

abcxxxxxx

解析

1.string库函数

        首先如果不用KMP算法,我们可以使用C++string库中自带的库函数,也可以轻松解决这道问题,我们来看一下代码:

#include<iostream>
#include<cstring>
using namespace std;
char* locate(char* s, char* e)
{
	string m = s;
	int num = m.find(e);
	if (num == -1)
		throw "non_found";
	//cout << "num=" << num << endl;
	return (s + num);
}
int main()
{
	try
	{
		char a[] = "hello world";
		char b[] = "world";
		char d[] = "print";
		char* result = locate(a, b);
		while (*result != '\0')
			cout << *(result++);
	}
	catch (const char*ss)
	{
		cout << ss << endl;
	}
	return 0;
}

 解释一下:传入两个参数,分别是待查询的字符串和目标子串。然后调用string库中的find函数,寻找子串在主串中的位置,如果没有找到,抛出异常,如果找到了则从这个位置开始,返回剩余全部主串;

2.使用KMP算法思想

char* locatesubstr(char* str1, char* str2)
{
	if (*str2 != '\0')
		while (*str1 != '\0')
		{
			for (int i = 0; *(str1 + i) == *(str2 + i); i++)
				if (*(str2 + i + 1) == '\0')
					return str1;
			str1++;
		}
	return NULL;
}

这段代码看着好像难以理解,我们加一些输出作为调试,来看看效果怎么样:

注解1

#include<iostream>
#include<cstring>
using namespace std;
char* locate(char* s, char* e)
{
	string m = s;
	int num = m.find(e);
	if (num == -1)
		throw "non_found";
	//cout << "num=" << num << endl;
	return (s + num);
}
char* locatesubstr(char* str1, char* str2)
{
	if (*str2 != '\0')
		while (*str1 != '\0')
		{
			for (int i = 0; *(str1 + i) == *(str2 + i); i++)
			{
				cout << "i的值为:" << i << endl;
				if (*(str2 + i + 1) == '\0')
					return str1;
			}
            throw "non_found";
			cout << "str1++" << endl;
			str1++;
		}
	return NULL;
}
int main()
{
	system("color 0A");
	try
	{
		char a[] = "hello world";
		char b[] = "world";
		char d[] = "print";
		char* result = locate(a, b);
		while (*result != '\0')
			cout << *(result++);
		cout << endl;
		char* results = locatesubstr(a, b);
		while (*results != '\0')
			cout << *(results++);
	}
	catch (const char*ss)
	{
		cout << ss << endl;
	}
	return 0;
}

 输出的结果为:

        我们发现,首先,str1++这句代码执行了6次,i的值被修改了5次。 根据代码我们不难发现,这段代码的实现方法是,首先找到和子串首字符相同的字符,看看后面的字符是否也相同

对我们调试程序输入的hello world 所运行出的结果的解释:

首先,i = 0;for循环满足的条件是*str1 == *str2,显然前6个字符都不满足。

根据BF算法,主串向后移动6次;

从第7个字符开始,程序最终进入for循环,继续依次比较子串和主串后面的内容,

因为每次都满足条件*(str1 + i) == *(str2 + i);所以i持续自加,直到自加5次后子串比较完毕,

*(str2 + i + 1) == '\0',也就是寻找成功,返回移动后的主串。

最终通过主程序输出了world。

注解2

下面的例子,我们测试一个找不到的情况:

int main()
{
	system("color 0A");
	try
	{
		char a[] = "hello world";
		char b[] = "world";
		char d[] = "print";
		char* results = locatesubstr(a, d);
		while (*results != '\0')
			cout << *(results++);
	}
	catch (const char*ss)
	{
		cout << ss << endl;
	}
	return 0;
}

运行结果为:

发现str1一直在比较并向后移动,最终返回NULL值。

注解3

再换一个:

int main()
{
	system("color 0A");
	try
	{
		char a[] = "hello world";
		char b[] = "world";
		char d[] = "print";
		char e[] = "word";
		char* results = locatesubstr(a, e);
		while (*results != '\0')
			cout << *(results++);
	}
	catch (const char*ss)
	{
		cout << ss << endl;
	}
	return 0;
}

 

发现如我们所想,主串先向后移动6次,

然后word前三个字符相同,进入for循环,i自加3次,

发现第四个字符不同,主串继续向后移动strlen(world)这么多次,

最终返回NULL值。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

学懂缓存雪崩,缓存击穿,缓存穿透仅需一篇,基于Redis讲解

在了解缓存雪崩、击穿、穿透这三个问题前&#xff0c;我们需要知道为什么我们需要缓存。在了解这三个问题后&#xff0c;我们也必须知道使用Redis时&#xff0c;如何解决这些问题。 所以我将按照"为什么我们需要缓存"、"什么是缓存雪崩、击穿、穿透"、&qu…

​字创未来 方正字库第十二届“方正奖”设计大赛正式来袭

传承汉字文化精髓&#xff0c;方正字库在字体行业不断探索深耕。方正字库一直致力于弘扬中华汉字文化&#xff0c;不断促进行业字体设计创新发展。于2001年在行业最艰难的时候&#xff0c;怀揣着对字体设计未来的美好向往&#xff0c;首届“北大方正奖”印刷字体设计大赛&#…

家政服务预约APP的系统设计与实现

摘 要&#xff1a;针对家政行业蓬勃发展&#xff0c;老套的家政服务方式已经跟不上互联网时代的步伐这个问题。基于Android移动平台的分析和设计过程、C/S模式、Eclipse平台&#xff0c;采用Java语言进行开发设计&#xff0c;设计了基于MVC架构的实现方案。安卓客户端与服务器…

Flume系列:Flume通道拓扑结构

目录 Apache Hadoop生态-目录汇总-持续更新 1: 基础架构 2&#xff1a;简单串联 3&#xff1a;复制(Replicating)和多路复用(Multiplexing) 4&#xff1a;负载均衡和故障转移 5&#xff1a;聚合 Apache Hadoop生态-目录汇总-持续更新 系统环境&#xff1a;centos7 Java环境…

IDEA 创建 Springmvc 项目

一、概述 在18年的时候就开始接触 SpringBoot &#xff0c;然后就一直在使用它。众所周知 SpringBoot 内嵌 Tomcat&#xff0c;后续再也没有单独新建过Web 项目。作为IDEA 的用户&#xff0c;总想要用它来建一个Web 项目自己跑一跑&#xff0c;但建项目不是我最终目的~~ &…

好用的自动化框架-Allure

概述 报告主要包含总览、类别、测试套件、图表、时间刻度、功能、包等7大部分&#xff0c;支持自定义诸多信息&#xff0c;包括附件添加、缺陷链接、案例链接、测试步骤、Epic、Feature、Story、Title、案例级别等&#xff0c;相当强大。 allure与pytest的结合使用可以呈现完…

ProtoBuf 语法(一)

系列文章 ProtoBuf 语法&#xff08;二&#xff09; ProtoBuf 语法&#xff08;三&#xff09; 文章目录 前言一、字段规则二、消息类型的定义与使用2.1 定义2.2 使用 三、enum 类型3.1 定义规则3.2 注意事项 四、any 类型4.1 类型说明4.2 类型使用 五、oneof 类型六、map 类型…

【Vue】二:Vue核心处理---计算属性 监视属性

文章目录 1.计算属性示例2. 监听属性3.补充 1.计算属性示例 实际上计算属性与methods中定义方法基本上没有什么区别&#xff0c;只是计算属性基于响应式依赖缓存&#xff0c;只要数据没有发生改变&#xff0c;计算属性从缓存中取值&#xff0c;只有当数据发送改变&#xff0c;才…

安卓中集成高德地图

安卓中集成高德地图 1.高德地图的优缺点 高德开放平台 | 高德地图API 高德地图优点&#xff1a; 1、领先的地图渲染技术&#xff1a;性能提升10倍&#xff0c;所占空间降低80&#xff05;&#xff0c;比传统地图软件节省流量超过90&#xff05; 2、专业在线导航功能&#x…

idea模板配置

idea版本&#xff1a;2023.1 未设置模板的idea&#xff0c;新建类会自动生成类注释 格式如下&#xff1a; /*** author user* date 2023/5/20 0020 14:25*/ public class User {} 其中&#xff0c;user为当前用户名 这里&#xff0c;如果希望将类注释改写成如下&#xff0…

档案馆空气质量在线3D监控系统温湿度方案

档案馆库房八防温湿度空气质量一体化解决方案 档案库房是档案事业发展的基石&#xff0c;其主要任务是集中保管国家机构及个人等在各种形式下形成的具有一定价值和保存价值的各种载体档案&#xff0c;主要包括文书档案、科技档案、会计档案、人事档案、实物档案等。随着我国经济…

X2000 freeRTOS usb_bulk通信

例程 官方例程..\freertos\example\usb\device\gadget_generic_bulk.c&#xff0c;代码如下&#xff1a; #include <common.h> #include <usb/gadget_bulk.h> #include <os.h>static const struct gadget_id bulk_id {.vendor_id 0x1CBE,.product_id 0x…

【数据生成】——Semantic Image Synthesis via Diffusion Models语义分割数据集生成论文浅读

语义分割&#xff0c;数据生成 摘要 Denoising Diffusion Probabilistic Models (DDPMs) 在各种图像生成任务中取得了显著的成功&#xff0c;相比之下&#xff0c;生成对抗网络 (GANs) 的表现不尽如人意。最近的语义图像合成工作主要遵循事实上的基于 GAN 的方法&#xff0c;…

直流电机 PID 控制系统仿真研究(Simulink实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

python+vue高校网上跳蚤二手市场的设计与实现

商品信息是卖家供应用户必不可少的一个部分。在跳蚤市场发展的整个过程中&#xff0c;商品担负着最重要的角色。为满足如今日益复杂的管理需求&#xff0c;各类管理系统程序也在不断改进。本课题所设计的普通高校网上跳蚤市场&#xff0c;使用Django框架&#xff0c;Python语言…

【信号变化检测】使用新颖的短时间条件局部峰值速率特征进行信号变化/事件/异常检测(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

网络安全复习

目录 低层协议安全性 IP协议 ARP协议 TCP协议 NAT协议 单钥加密体制 DES算法 课后习题 双钥加密体制 &#x1f407;怎么说 欧几里得算法求逆 RSA算法 椭圆曲线加密 Diffie- Hellman 密钥交换算法 ElGamal签名机制 Schnorr签名机制 DSS签名算法——DSA 低层协…

HTML+CSS实训——Day02——仿一个网易云音乐的登陆界面

仓库链接:https://github.com/MengFanjun020906/HTML_SX 前言 今天要继续完成我们的音乐软件了&#xff0c;昨天写完了封面&#xff0c;今天该完成开屏广告和登陆界面了。 登陆界面代码 <!DOCTYPE html> <html lang"en"> <head><meta charse…

【P35】JMeter 包含控制器(Include Controller)

文章目录 一、包含控制器&#xff08;Include Controller&#xff09;参数说明二、准备工作三、测试计划设计3.1、保存测试片段3.2、使用测试片段 一、包含控制器&#xff08;Include Controller&#xff09;参数说明 可以将测试计划的某一部分提取为公用逻辑&#xff0c;这样…

【十字绣】传统手艺-微信小程序开发流程详解

还记得小时候看过母亲的十字绣吗&#xff0c;易学易懂&#xff0c;就是用专用的绣线和十字格布&#xff0c;通过平面坐标计找出位置&#xff0c;对照专用的图案进行刺绣&#xff0c;可作出心中所想的画&#xff0c;奈何所需材料成本不小&#xff0c;这里用小程序简单模拟十字绣…