当前位置: 首页 > article >正文

【C++】P5734 【深基6.例6】文字处理软件


在这里插入图片描述

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

文章目录

  • 💯前言
  • 💯题目描述
  • 💯题目描述
    • 输入格式
    • 输出格式
    • 示例输入与输出
      • 输入:
      • 输出:
  • 💯我的做法
    • 操作1:在文档末尾插入字符串
    • 操作2:截取字符串
    • 操作3:在指定位置插入字符串
    • 操作4:查找子串位置
    • 完整代码:
  • 💯老师的做法
    • 主要差异
    • 代码:
  • 💯对比分析
    • 相同点:
    • 差异点:
  • 💯扩展与优化
  • 💯小结


在这里插入图片描述


💯前言

  • 在本次编程练习中,我们的目标是设计并实现一款文字处理软件。题目要求我们通过一系列字符串操作,模拟文字处理过程。这些操作包括字符串的拼接、截取、插入和查找,操作的结果需及时输出。这类问题不仅考察了我们对 C++ 中字符串操作的掌握,也考察了如何根据不同需求选择合适的数据结构和算法。通过这篇文章,我们将详细分析题目中的要求、我的实现方法、老师的实现方式,并进行对比,最终扩展和总结整个思路。
    C++ 参考手册
    在这里插入图片描述

💯题目描述

以下是题目原文,要求根据输入的操作来处理文档内容,并输出结果:

💯题目描述

P5734 【深基6.例6】文字处理软件
在这里插入图片描述

你需要开发一款文字处理软件。最开始时输入一个字符串作为初始文档。可以认为文档开头是第 0 个字符。需要支持以下操作:

  • 1 str:后接插入,在文档后面插入字符串 str,并输出文档的字符串;
  • 2 a b:截取文档部分,只保留文档中从第 a 个字符起 b 个字符,并输出文档的字符串;
  • 3 a str:插入片段,在文档中第 a 个字符前面插入字符串 str,并输出文档的字符串;
  • 4 str:查找子串,查找字符串 str 在文档中最先的位置并输出;如果找不到输出 -1

为了简化问题,规定初始的文档和每次操作中的 str 都不含有空格或换行。最多会有 q 次操作。

输入格式

第一行输入一个正整数 q,表示操作次数。

第二行输入一个字符串 str,表示最开始的字符串。

第三行开始,往下 q 行,每行表示一个操作,操作如题目描述所示。

输出格式

一共输出 q 行。

对于每个操作 1,2,3,根据操作的要求输出一个字符串。

对于操作 4,根据操作的要求输出一个整数。

示例输入与输出

输入:

4
ILove
1 Luogu
2 5 5
3 3 guGugu
4 gu

输出:

ILoveLuogu
Luogu
LuoguGugugu
3

💯我的做法

在我自己的实现中,我依赖了 C++ 中标准库提供的 string 类型,它使得字符串操作变得非常简单。主要操作如下:

操作1:在文档末尾插入字符串

我选择了使用 += 运算符来将字符串拼接到文档末尾,代码如下:

s += str;

这样实现可以将新字符串 str 添加到当前文档 s 的末尾,符合题目的要求。

操作2:截取字符串

对于操作2,我使用了 substr(a, b) 函数来截取文档中的一部分。substr 函数接受两个参数,a 为起始位置,b 为截取长度。根据题目要求,我们需要将起始位置从 1-based 转换为 0-based,因此在调用 substr 时,将 a - 1 作为起始位置:

s = s.substr(a - 1, b);

操作3:在指定位置插入字符串

为了在指定位置插入字符串,我使用了 insert(a, str) 方法。这个方法会将字符串 str 插入到当前字符串 s 的第 a 个位置:

s.insert(a - 1, str);

注意这里的 a - 1 是因为题目给定的是 1-based 索引,而 C++ 的字符串操作是基于 0-based 索引的。

操作4:查找子串位置

对于操作4,我使用了 find(str) 函数来查找子串 str 在文档中最早出现的位置。如果没有找到该子串,find 函数会返回 string::npos,表示未找到:

size_t pos = s.find(str);
if (pos == string::npos)
    cout << -1 << endl;
else
    cout << pos << endl;

完整代码:

#include <iostream>
#include <string>
using namespace std;

int main()
{
 	int n;
 	cin >> n;
 	string s;
 	cin >> s;
 	while(n--)
 	{
 		int m;
 		cin >> m;
 		switch(m)
 		{
 			case 1:
				{
				string s2;
 				cin >> s2;
 				s += s2;
 				cout << s << endl;
 				break;
				}
 			case 2:
				{
				int a, b;
 				cin >> a >> b;
 				s = s.substr(a, b);
 				cout << s << endl;
 				break;
				}
 			case 3:
				{
				int a;
 				string s2;
 				cin >> a >> s2;
 				s.insert(a, s2);
 				cout << s << endl;
 				break;
				}
 			case 4:
				{
				string s2;
 				cin >>  s2;
 				size_t idex = s.find(s2);
 				if(idex == string::npos)
 				    cout << -1 << endl;
 				else
 				    cout << idex << endl;
 				break;
				}
		}
	}
	 	
	return 0;
}

💯老师的做法

老师的做法和我类似,核心思路没有变化,采用了 C++ 标准库的 string 类型及其内置的操作函数。具体代码如下:

主要差异

  1. 变量初始化

    • 老师在代码开始时就预定义了变量 a, b, 和 str,而我的做法是在每个操作中根据需要动态定义这些变量。
    • 老师的代码将变量定义放在了 while 循环外部,而我的做法将这些变量放在了每个 switch 语句内,确保了在每个操作中只定义所需变量。
  2. 使用 switch 语句

    • 老师使用了 switch 语句来处理不同的操作,明确区分了不同的操作类型。这种方式在处理多个互斥操作时非常清晰,且便于扩展。
  3. 查找操作

    • 在查找子串的部分,老师也使用了 find 函数,并且处理了找不到子串时返回 -1 的逻辑,和我的做法相同。

代码:

#include <iostream>
#include <string>
using namespace std;

int main()
{
    int q = 0;
    cin >> q;
    string s;
    cin >> s;
    int a, b;
    string str;

    while (q--)
    {
        int m = 0;
        cin >> m;
        switch (m)
        {
        case 1:
            cin >> str;
            s += str;
            cout << s << endl;
            break;
        case 2:
            cin >> a >> b;
            s = s.substr(a, b);
            cout << s << endl;
            break;
        case 3:
            cin >> a >> str;
            s.insert(a, str);
            cout << s << endl;
            break;
        case 4:
            cin >> str;
            size_t pos = s.find(str);
            if (pos == string::npos)
                cout << -1 << endl;
            else
                cout << pos << endl;
            break;
        }
    }
    return 0;
}

💯对比分析

相同点:

  1. 操作逻辑

    • 两种实现都处理了 4 种操作,分别是插入、截取、插入指定位置、查找子串。
    • 都使用了 string 类型的操作函数,如 +=, substr, insert, 和 find 来执行字符串操作。
  2. 输入输出

    • 输入格式一致,读取 q 次操作并执行,每次执行后输出对应结果。

差异点:

  1. 变量定义

    • 我的做法在每个操作前定义变量,使得每次操作只在需要的时候初始化变量。老师则将变量统一提前定义,这在一些情况下可能更清晰,尤其是在处理较为复杂的逻辑时。
  2. 代码结构

    • 我选择了将每个操作的代码放在 switch 语句的各个分支中,老师则将更多的内容放在 switch 外部,尤其是变量的定义和初始化。

💯扩展与优化

  1. 优化字符串拼接

    • 在频繁拼接字符串的情况下,+= 运算符可能会有性能问题,尤其是当字符串较长时。为了提高效率,可以使用 stringstreamvector<char> 来减少内存重分配带来的开销。
  2. 边界检查

    • 对于操作 2 和操作 3,程序没有进行充分的边界检查。如果 ab 超出了文档长度范围,应当做适当的处理。比如,在执行 substr(a, b) 时,可以检查 a + b 是否超过字符串的最大长度。
  3. 容错性

    • 对于查找子串操作,可以加入更多的异常处理机制,例如对输入的子串进行合法性校验,防止空串或无效字符导致异常。

💯小结

本次文字处理软件题目考察了 C++ 中字符串的基本操作,特别是如何通过不同的方式处理字符串的拼接、截取、插入和查找。通过两种实现方法的对比,我们不仅看到了不同的实现方式,也发现了每种方法的优缺点。在实际编码中,我们可以根据具体情况选择合适的方式来实现。通过这些操作,我们能够更深入地理解 C++ 字符串的操作特性,并提升自己的编程能力。


在这里插入图片描述


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


http://www.kler.cn/a/531622.html

相关文章:

  • redis底层数据结构
  • 93,【1】buuctf web [网鼎杯 2020 朱雀组]phpweb
  • 大模型领域的Scaling Law的含义及作用
  • 基于深度学习的输电线路缺陷检测算法研究(论文+源码)
  • 谭浩强C语言程序设计(4) 8章(下)
  • 梯度提升用于高效的分类与回归
  • 使用Walk()遍历目录
  • Mac电脑上好用的免费截图软件
  • 【Linux】进程状态和优先级
  • Vue.js组件开发-实现左侧浮动菜单跟随页面滚动
  • FreeRTOS学习笔记3:系统配置文件+任务创建和删除的API函数介绍
  • 实验十一 Servlet(二)
  • 重新刷题求职2-DAY1
  • 鸟哥Linux私房菜第四部分
  • 【文件上传】
  • webpack-编译原理
  • 基于SpringBoot的美食烹饪互动平台的设计与实现(源码+SQL脚本+LW+部署讲解等)
  • 一些单转多路电源芯片介绍及使用
  • 电脑开机键一闪一闪打不开
  • 热点账户优化和影子表压测
  • Mac电脑上好用的压缩软件
  • 普罗米修斯监控服务搭建位置全解析:权衡与抉择
  • 在客户现场可快速落地体验的智慧能源开源了。
  • Maven工程核心概念GAVP详解:从命名规范到项目协作的基石
  • 一文讲解HashMap线程安全相关问题(下)
  • Java—双列集合