【C++】B2118 验证子串


在这里插入图片描述

博客主页: [小ᶻ☡꙳ᵃⁱᵍᶜ꙳]
本文专栏: C++

文章目录

  • 💯前言
  • 💯题目概述
    • 题目描述
    • 输入格式
    • 输出格式
    • 输入输出样例
      • 样例 1
      • 样例 2
    • 题目提示
  • 💯解决方案分析
    • 初步分析与思路
  • 💯我的代码实现与分析
    • 代码回顾
    • 实现逻辑与优缺点
      • 优点:
      • 问题与改进:
    • 总结
  • 💯老师的代码实现与分析
    • 代码回顾
    • 核心逻辑分析
    • 总结
  • 💯优化与扩展
    • 优化输入处理
    • 扩展功能:查找子串位置
  • 💯小结


在这里插入图片描述


💯前言

  • 在编程竞赛中,字符串处理是一个经常出现且非常重要的主题。无论是子串匹配、字符串翻转还是查找模式,字符串问题都涉及到很多算法的运用和优化思路。今天,我们以一个经典的字符串题目为例,详细探讨如何验证两个字符串之间的子串关系。本文不仅会分析题目和给出的不同解法,还会介绍核心函数 strstr 的功能,并对代码进行优化和扩展,最终形成一个完整的学习框架。
    C++ 参考手册
    在这里插入图片描述


💯题目概述

B2118 验证子串
在这里插入图片描述

题目描述

输入两个字符串,验证其中一个字符串是否为另一个字符串的子串。

输入格式

两个字符串,每行一个字符串。

输出格式

  • 如果第一个字符串是第二个字符串的子串,输出:
    (s1) is substring of (s2)
    
  • 如果第二个字符串是第一个字符串的子串,输出:
    (s2) is substring of (s1)
    
  • 如果两者都不是对方的子串,输出:
    No substring
    

输入输出样例

样例 1

输入:

abc
dddncabca

输出:

abc is substring of dddncabca

样例 2

输入:

aaa
bbb

输出:

No substring

题目提示

对于 100% 的数据,字符串长度不会超过 20。


💯解决方案分析

初步分析与思路

子串验证问题本质上是一个字符串匹配问题。对于两个字符串 s 1 s_1 s1 s 2 s_2 s2

  1. s 1 s_1 s1 s 2 s_2 s2 的子串,则 s 1 s_1 s1 s 2 s_2 s2 中出现,并且顺序保持一致。
  2. s 2 s_2 s2 s 1 s_1 s1 的子串,则 s 2 s_2 s2 s 1 s_1 s1 中出现,并且顺序保持一致。
  3. 如果两者都不是对方的子串,则不存在子串关系。

题目限制了字符串的长度不超过 20,这意味着暴力解决方案的时间复杂度较低时仍可以接受。然而,为了提升效率与代码的可读性,我们可以借助 C++ 的内置字符串操作函数。

下面我们会分别解析两种做法:

  1. 我的代码实现:基于字符逐个比较的实现。
  2. 老师的代码实现:基于标准库 strstr 函数的实现。

同时,我们会对代码进行优化和扩展,探讨更通用的处理方法。


💯我的代码实现与分析

代码回顾

我的代码如下:

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;

const int N = 25;
char ch1[N];
char ch2[N];

int main()
{
    cin >> ch1;
    cin >> ch2;

    int len1 = strlen(ch1);
    int len2 = strlen(ch2);

    int i = 0, j = 0, count1 = 0, count2 = 0;
    for (i = 0; i < len1; i++) {
        for (j = 0; j < len2; j++) {
            if (ch1[i] == ch2[j]) {
                count1++;
                break;
            }
        }
    }

    for (i = 0; i < len2; i++) {
        for (j = 0; j < len1; j++) {
            if (ch2[i] == ch1[j]) {
                count2++;
                break;
            }
        }
    }

    if (count1 == len1) {
        cout << ch1 << " is substring of " << ch2 << endl;
    } else if (count2 == len2) {
        cout << ch2 << " is substring of " << ch1 << endl;
    } else {
        cout << "No substring" << endl;
    }
    return 0;
}

在这里插入图片描述

实现逻辑与优缺点

优点:

  1. 代码思路清晰,易于理解。
  2. 通过双重循环,尝试逐个字符匹配,确保了每个字符都得到验证。

问题与改进:

  1. 错误的逻辑:

    • 我统计了两个字符串中每个字符是否能在另一个字符串中找到,但这并不能验证子串的顺序关系。
    • 例如,对于输入:
      abc
      cab
      
      我的代码会误判 abccab 的子串,因为所有字符都能匹配,但实际顺序并不一致。
  2. 效率较低:

    • 代码中使用了双重循环,导致时间复杂度为 O ( n 2 ) O(n^2) O(n2)。当字符串长度较小时,问题不大,但如果题目限制放宽,这种方法的效率会成为瓶颈。
  3. 冗余的计数变量:

    • count1count2 的逻辑本质上与判断子串无关,可以省略。

总结

虽然我的代码在小范围数据下可以完成任务,但存在逻辑漏洞,且效率和可读性都可以进一步优化。


💯老师的代码实现与分析

代码回顾

以下是老师的代码:

#include <iostream>
#include <cstring>

using namespace std;

const int N = 20;
char s1[N];
char s2[N];

int main() {
    cin >> s1;
    cin >> s2;

    if (strstr(s2, s1))
        cout << s1 << " is substring of " << s2 << endl;
    else if (strstr(s1, s2))
        cout << s2 << " is substring of " << s1 << endl;
    else
        cout << "No substring" << endl;

    return 0;
}

在这里插入图片描述

核心逻辑分析

  1. strstr 函数的使用

    • 定义:
      const char* strstr(const char* str1, const char* str2);
      
      • strstr 用于查找字符串 str2 是否是字符串 str1 的子串。
      • 如果找到子串,返回指向 str1 中子串起始位置的指针。
      • 如果没有找到,返回 NULL
    • 在本题中,分别使用:
      • strstr(s2, s1) 检查 s 1 s_1 s1 是否为 s 2 s_2 s2 的子串。
      • strstr(s1, s2) 检查 s 2 s_2 s2 是否为 s 1 s_1 s1 的子串。
  2. 逻辑清晰且高效

    • 判断 s 1 s_1 s1 s 2 s_2 s2 的子串关系时,直接调用 strstr,避免了手动遍历字符。
    • 相比双重循环的暴力方法,strstr 内部可能采用优化的字符串匹配算法(如 KMP 算法),使时间复杂度接近 O ( n ) O(n) O(n)
  3. 简洁性与可读性

    • 整体代码逻辑简单明了,无需额外的计数或复杂的循环。
    • 代码长度短,功能却完整。

总结

老师的代码实现了简单、高效、可靠的子串验证,适合直接解决题目需求。


💯优化与扩展

优化输入处理

  1. 防止输入溢出:
    当前代码中,输入字符串长度如果超过 N - 1(20),可能导致缓冲区溢出。
    可以使用 cin.getline 限制输入长度:

    cin.getline(s1, N);
    cin.getline(s2, N);
    
  2. 空字符串处理:
    如果输入为空字符串,程序应该直接输出 No substring,而不是调用 strstr

    if (strlen(s1) == 0 || strlen(s2) == 0) {
        cout << "No substring" << endl;
        return 0;
    }
    

扩展功能:查找子串位置

如果需要输出子串的位置,可以通过 strstr 的返回值计算:

const char* result = strstr(s2, s1);
if (result) {
    cout << s1 << " is substring of " << s2 << " at position " << (result - s2) << endl;
}

💯小结

通过对本题的解析,我们不仅学习了子串验证的基本方法,还深入了解了 strstr 函数的强大功能及其高效性。同时,通过比较不同实现方法,我们发现了代码优化的重要性和标准库的优势。在实际开发中,合理利用现有工具可以显著提高代码质量和开发效率。

希望本文能够帮助读者更好地理解字符串处理问题,提升编程能力!


在这里插入图片描述


在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述

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

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

相关文章

68.基于SpringBoot + Vue实现的前后端分离-心灵治愈交流平台系统(项目 + 论文PPT)

项目介绍 本系统将严格按照软件开发流程进行各个阶段的工作&#xff0c;采用B/S架构&#xff0c;面向对象编程思想进行项目开发。在引言中&#xff0c;作者将论述心灵治愈交流平台的当前背景以及系统开发的目的&#xff0c;后续章节将严格按照软件开发流程&#xff0c;对系统进…

【分布式缓存】一致性Hash原理剖析,一致性Hash与Hash的区别(详解)

文章目录 Hash算法Hash算法的缺陷一致性Hash算法一致性Hash存储规则一致性Hash解决Hash的缺陷问题一致性Hash的偏斜问题一致性哈希在实际中的应用总结 更多相关内容可查看 假设有一个场景&#xff1a;有三万张图片&#xff0c;有三台服务器S0&#xff0c;S1&#xff0c;S2 要求…

Clisoft SOS与CAD系统集成

Clisoft SOS与CAD系统集成 以下内容大部分来自官方文档&#xff0c;目前只用到与Cadence Virtuoso集成&#xff0c;其他还未用到&#xff0c;如有问题或相关建议&#xff0c;可以留言。 与Keysight ADS集成 更新SOS客户端配置文件sos.cfg&#xff0c;以包含支持ADS的模板&am…

Java-数据结构-链表-高频面试题(1)

在上一篇文章中&#xff0c;我们学习了链表中的"单向链表"&#xff0c;但学可不代表就是学会了&#xff0c;能够运用链表的地方比比皆是&#xff0c;解题方法也是层出不穷&#xff0c;今天就让我们巩固一下"单向链表"的知识吧~ 第一题&#xff1a;相交链表…

JVM实战—OOM的定位和解决

1.如何对系统的OOM异常进行监控和报警 (1)最佳的解决方案 最佳的OOM监控方案就是&#xff1a;建立一套监控平台&#xff0c;比如搭建Zabbix、Open-Falcon之类的监控平台。如果有监控平台&#xff0c;就可以接入系统异常的监控和报警&#xff0c;可以设置当系统出现OOM异常&…

照片做成图书小程序开发制作介绍

照片做成图书小程序系统&#xff0c;主要是让用户直接通过小程序选择需要做成书的类型和照片排版布局模板&#xff0c;以及上传照片的数量。照片上传完成后&#xff0c;生成模板图片样式进行预览或编辑修改。修改完成全部保存。保存后生成完整的照片书进行预览没问题&#xff0…

云商城--业务+架构学习和环境准备

云商城业务架构学习和环境准备 B2B&#xff1a;Business to Business&#xff0c;交易双方的身份都是商家&#xff0c;也就是商家将商品卖给商家&#xff0c;类似采购、批发类购物&#xff0c;国内代表性网站阿里巴巴批发网 C2C&#xff1a;Customer to Customer&#xff0c;…

Elasticsearch:Lucene 2024 年回顾

作者&#xff1a;来自 Elastic Chris Hegarty 2024 年对于 Apache Lucene 来说又是重要的一年。在本篇博文中&#xff0c;我们将探讨主要亮点。 Apache Lucene 在 2024 年表现出色&#xff0c;发布了许多版本&#xff0c;包括三年来的首次重大更新&#xff0c;其中包含令人兴奋…

基于LabVIEW的BeamGage自动化接口应用

设置 National Instruments LabVIEW可执行程序需要被配置为使用.NET 4框架。.NET允许自定义可执行程序的运行方式。可通过以下方式实现&#xff1a; 在LabVIEW安装目录中创建一个名为LabVIEW.exe.config的文本文件&#xff08;例如&#xff1a;C:\Program Files\National Ins…

卸载干净 IDEA(图文讲解)

目录 1、卸载 IDEA 程序 2、注册表清理 3、残留清理 1、卸载 IDEA 程序 点击屏幕左下角 Windows 图标 -> 设置-控制面板->intellij idea 勾选第一栏 Delete IntelliJ IDEA 2022.2 caches and local history&#xff0c;表示同时删除 IDEA 本地缓存以及历史。 Delete I…

李宏毅机器学习课程笔记02 | 机器学习任务攻略General Guide

第一步&#xff1a;分析loss on training data 先检查在训练数据上模型是否很好的学习 情况1&#xff1a;如果在训练集上&#xff0c;loss很大&#xff0c;说明在训练资料上没有训练好 可能性1&#xff1a;设置的模型太简单了&#xff0c;模型存在model bias模型偏差&#x…

【C++】19.多态

文章目录 1. 多态的概念2. 多态的定义及实现2.1 多态的构成条件2.1.1 实现多态还有两个必须重要条件&#xff1a;2.1.2 虚函数 (Virtual Function)定义&#xff1a;特性&#xff1a;示例代码&#xff1a;代码分析1. 类定义部分2. 主函数部分运行结果 重点讲解1. 虚函数的作用2.…

光伏仿真与设计系统应用架构深度剖析

在光伏产业蓬勃发展的时代背景下&#xff0c;绿虫光伏仿真与设计系统成为推动其高效发展的核心力量。其应用架构涵盖多个关键步骤&#xff0c;每个环节都紧密相扣&#xff0c;共同构建起精准且高效的设计体系。 气象分析作为开篇之笔&#xff0c;起着基石般的重要作用。系统全…

进程间通讯

简介&#xff1a; 进程间通讯方式有&#xff1a; 1.内存映射&#xff08;mmap&#xff09;&#xff1a; 使用mmap函数将磁盘空间映射到内存 2.管道 3.信号 4.套接字&#xff08;socket&#xff09; 5.信号机制 通过进程中kill函数&#xff0c;去给另一个函数发送信号&a…

空压机接入配置实例:利用 MODBUS - TCP 转 Ethernet IP 网关实现连接

在工业自动化生产环境中&#xff0c;空压机作为重要的气源设备&#xff0c;其稳定运行和有效监控对于整个生产流程至关重要。然而&#xff0c;不同厂家生产的空压机可能采用不同的通信协议&#xff0c;这给集中监控和管理带来了挑战。在本次案例中&#xff0c;我们遇到的空压机…

基于 Boost.Asio 和 Boost.Beast 的异步 HTTP 服务器(学习记录)

已完成功能&#xff1a; 支持 GET 和 POST 请求的路由与回调处理。 解析URL请求。 单例模式 管理核心业务逻辑。 异步 I/O 技术和 定时器 控制超时。 通过回调函数注册机制&#xff0c;可以灵活地为不同的 URL 路由注册处理函数。 1. 项目背景 1.1 项目简介 本项目是一个基于…

Harmony开发【笔记1】报错解决(字段名写错了。。)

在利用axios从网络接收请求时&#xff0c;发现返回obj的code为“-1”&#xff0c;非常不解&#xff0c;利用console.log测试&#xff0c;更加不解&#xff0c;可知抛出错误是 “ E 其他错误: userName required”。但是我在测试时&#xff0c;它并没有体现为空&#xff0c;…

Spring源码分析之事件机制——观察者模式(二)

目录 获取监听器的入口方法 实际检索监听器的核心方法 监听器类型检查方法 监听器的注册过程 监听器的存储结构 过程总结 Spring源码分析之事件机制——观察者模式&#xff08;一&#xff09;-CSDN博客 Spring源码分析之事件机制——观察者模式&#xff08;二&#xff…

关于Mac中的shell

1 MacOS中的shell 介绍&#xff1a; 在 macOS 系统中&#xff0c;Shell 是命令行与系统交互的工具&#xff0c;用于执行命令、运行脚本和管理系统。macOS 提供了多种 Shell&#xff0c;主要包括 bash 和 zsh。在 macOS Catalina&#xff08;10.15&#xff09;之前&#xff0c…

【C++】20.二叉搜索树

文章目录 1. 二叉搜索树的概念2. 二叉搜索树的性能分析3. 二叉搜索树的插入4. 二叉搜索树的查找5. 二叉搜索树的删除6. 二叉搜索树的实现代码7. 二叉搜索树key和key/value使用场景7.1 key搜索场景&#xff1a;7.2 key/value搜索场景&#xff1a;7.3 主要区别&#xff1a;7.4 ke…