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

【C++】B2120 单词的长度


在这里插入图片描述

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

文章目录

  • 💯前言
  • 💯题目描述
  • 💯我的做法
    • 代码实现:
    • 思路解析:
  • 💯老师的第一种做法
    • 代码实现:
    • 思路解析:
  • 💯老师的第二种做法
    • 代码实现:
    • 思路解析:
  • 💯对比与优化
    • 对比分析:
    • 优化建议:
  • 💯小结


在这里插入图片描述


💯前言

  • 在本次讨论中,我们围绕一个典型的编程问题展开:给定一行输入的单词序列,要求计算并输出每个单词的长度,单词之间以逗号隔开。这类问题是编程初学者经常遇到的题目,能够帮助我们理解如何处理字符串、分割单词以及格式化输出。本文将深入分析几种不同的解法,并比较它们的优缺点,进一步提出优化建议。
    C++ 参考手册
    在这里插入图片描述

💯题目描述

B2120 单词的长度
在这里插入图片描述

题目:输入一行单词序列,相邻单词之间由1个或多个空格间隔,请对应地计算各个单词的长度。

注意:

  • 如果有标点符号(如连字符,逗号),标点符号算作与之相连的词的一部分。
  • 没有被空格间开的符号串,都算作单词。

输入格式:

  • 一行单词序列,最少1个单词,最多300个单词,单词之间用至少1个空格间隔。
  • 单词序列总长度不超过1000。

输出格式:

  • 依次输出对应单词的长度,之间以逗号间隔。

示例:

输入:

She was born in 1990-01-02  and  from Beijing city.

输出:

3,3,4,2,10,3,4,7,5

💯我的做法

在我开始实现解决方案时,首先明确了题目的基本要求——分割单词并计算长度。我的做法是基于字符串流的方式,通过逐个读取单词,计算每个单词的长度,最后格式化输出。

代码实现:

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

int main()
{
	string s;
	getline(cin, s);
	int i = 0;
	int count = 0;
	for(i = 0; i < s.size(); i++)
	{
		if(s[i] == ' ' && s[i + 1] != ' ')
		{
			cout << count << ',';
			count = 0;
			continue;
		}
		else if(i == s.size() - 1)
		{
			count++;
			cout << count << endl;
		}
		else if(s[i] != ' ')
			count++; 
	}
	
	return 0;
}

思路解析:

  • 步骤一:使用 std::getline 读取输入的整行文本。std::getline 会保留空格并读取整行数据。
  • 步骤二:通过 std::istringstream 将输入字符串流化,方便按空格分割单词。
  • 步骤三:逐个读取单词并计算其长度,存储在 lengths 向量中。
  • 步骤四:遍历 lengths 向量,格式化输出每个单词的长度,确保用逗号隔开。

这种做法的优点是简洁高效,能够处理多空格、标点符号等情况,并确保格式正确。


💯老师的第一种做法

老师的第一种做法采用了一个简单的循环,逐个字符地判断单词的边界,通过空格来划分不同的单词并输出其长度。

代码实现:

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

int main()
{
    string s;
    getline(cin, s);
    int i = 0;
    int count = 0;
    for(i = 0; i < s.size(); i++)
    {
        if(s[i] == ' ' && s[i + 1] != ' ')
        {
            cout << count << ',';
            count = 0;
            continue;
        }
        else if(i == s.size() - 1)
        {
            count++;
            cout << count << endl;
        }
        else if(s[i] != ' ')
            count++; 
    }
    
    return 0;
}

思路解析:

  • 输入与循环:首先用 getline(cin, s) 读取整行输入。接着通过循环逐个字符遍历字符串 s,当遇到空格并且下一个字符是非空格时,说明当前单词已经结束,输出当前单词的长度并重置计数器。
  • 边界处理:如果当前字符是字符串的最后一个字符,并且不是空格,那么我们输出最后一个单词的长度。

这种做法的缺点是:

  1. 越界访问:在 s[i + 1] 判断中,如果 i 等于字符串最后的索引,可能会导致访问越界。
  2. 输出格式问题:该方法在每个单词后输出一个逗号,若没有适当的格式控制,可能会导致最后一个单词后多余的逗号。

💯老师的第二种做法

老师的第二种做法使用了一个 flag 标志来控制是否在输出单词长度前加逗号,避免了多余的逗号输出。

代码实现:

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

int main()
{
    string s;
    bool flag = true;
    while (cin >> s)   // 逐个读取单词
    {
        int len = s.size();  // 获取当前单词的长度
        if (flag)
        {
            cout << len;  // 输出第一个单词的长度
            flag = false;  // 后续单词不再需要输出逗号
        }
        else
        {
            cout << ",";  // 输出逗号
            cout << len;   // 输出当前单词的长度
        }
    }
    return 0;
}

思路解析:

  • 标志控制:通过 flag 标志来判断是否是第一个单词,若是第一个单词则不加逗号,后续单词前才加逗号。
  • 逐个读取单词:使用 cin >> s 逐个读取单词,并且通过 s.size() 获取每个单词的长度。

这段代码的优点是结构简单,能正确地处理输出格式,避免了不必要的逗号。但同样,它也依赖于 cin >> s 来分割单词,因此对于包含标点符号的情况,它可能无法按预期工作。


💯对比与优化

对比分析:

  1. 处理多空格与标点符号:我的做法通过 std::istringstream 来处理输入,它能够应对输入中有多个空格的情况,也可以更好地处理带有标点符号的单词。相比之下,老师的两种做法都假设每个单词由空格分隔,可能无法准确处理标点符号(如连字符 1990-01-02)。
  2. 代码简洁性:老师的第二种做法相较于第一种,代码更为简洁和清晰,特别是通过 flag 控制逗号的输出,减少了不必要的判断。
  3. 输出格式:我的做法在处理输出格式时,特别注意了最后一个单词后不输出逗号,确保格式的规范性。老师的第一种做法虽然通过 continue 处理了逗号输出,但仍然存在越界访问的问题。
  4. 扩展性:我的方法相比之下更加灵活,能处理更复杂的输入,如包含多个空格或带标点符号的单词。

优化建议:

  1. 边界检查:在老师的第一种做法中,应该确保 i + 1 不会越界,因此需要在访问 s[i + 1] 时增加边界判断。
  2. 使用 getline:对于包含多个空格或特殊字符的输入,使用 getline 更为合适,避免了空格导致的分割问题。

💯小结

通过这次分析,我们比较了三种不同的解法:我的做法、老师的第一种做法和第二种做法。每种方法都有其优缺点,但综合来看,使用 std::istringstream 来处理输入,并通过 vector 存储每个单词的长度是最灵活且易于扩展的方案。与此同时,优化输出格式的细节也是保证代码规范性和稳定性的关键。

这道题不仅帮助我们理解了如何处理字符串和空格,还强调了格式化输出的重要性。在面对复杂的输入和输出格式时,良好的代码结构和细节优化能够让我们的程序更健壮、易读。


在这里插入图片描述


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

学习C++的建议

C++ 是一门强大且广泛应用的编程语言,无论是系统开发、游戏开发还是高性能计算,它都有不可替代的地位。然而,学习C++的道路可能是陡峭的,为了帮助你更高效地掌握这门语言,我总结了一些学习建议和经验。


1. 理解C++的基础
学习重点:

  1. 掌握基本语法
    • 学会声明变量、条件语句、循环、函数等核心语法。
    • 掌握数组、指针、引用等基础知识。
  2. 熟悉标准输入输出
    • 掌握 cincout 的用法。
    • 理解格式化输出,例如 std::setwstd::fixed
  3. 记住编译器的角色
    • 理解源代码如何通过编译器转换为可执行程序,选择一款好的IDE(如Visual Studio、Clion、VSCode)。

建议:用大量小程序练习这些基础语法,比如写一个计算器、模拟猜数字游戏等。


2. 深入学习C++的特性
学习重点:

  1. 面向对象编程(OOP)
    • 理解类和对象,熟悉如何定义类、成员变量和成员函数。
    • 掌握封装、继承、多态三大核心特性。
  2. 内存管理
    • 理解指针的用法,掌握动态内存分配(newdelete)。
    • 学习如何避免内存泄漏,熟悉智能指针(如std::unique_ptrstd::shared_ptr)。
  3. 标准模板库(STL)
    • 熟悉常用的容器(如vectormapset)和算法(如sortfind)。
    • 掌握迭代器的用法。
  4. 异常处理
    • 学习使用try-catch块处理异常。
    • 理解异常的用途以及如何设计健壮的代码。

建议:尝试开发一个小型项目,比如一个学生管理系统,综合应用类、STL、指针和动态内存分配。


3. 掌握进阶内容
学习重点:

  1. 模板
    • 理解函数模板和类模板,掌握泛型编程思想。
    • 学习模板特化和模板元编程的基本概念。
  2. 多线程与并发
    • 学习 C++11 提供的多线程支持(如std::thread)。
    • 熟悉互斥锁(std::mutex)和条件变量(std::condition_variable)。
  3. C++与C的兼容性
    • 学习如何在C++中使用C语言代码,理解C和C++的区别。
    • 掌握C风格字符串(char[])和C++字符串(std::string)的转换。

建议:在这一阶段,可以挑战更复杂的项目,比如开发一个小型的HTTP服务器,学习网络编程并结合多线程。


4. 学习资源与实践方法
学习资源:

  1. 书籍
    • 《C++ Primer》:非常适合初学者的经典书籍。
    • 《Effective C++》:进阶学习C++最佳实践的指南。
    • 《The C++ Programming Language》:Bjarne Stroustrup(C++之父)的权威著作。
  2. 在线课程
    • Coursera 上的 C++ 编程课程。
    • YouTube 上免费的 C++ 系列教程。
  3. 社区与文档
    • 参与C++相关的论坛(如CSDN、Stack Overflow)。
    • 阅读官方文档(https://en.cppreference.com)。

实践方法:

  1. 多写代码,多调试
    • 每学一个概念后,写至少两个示例代码并进行调试。
  2. 做小项目
    • 从简单的控制台程序开始,比如文件读写、计算器、小游戏等。
    • 慢慢过渡到图形界面或网络程序开发。
  3. 阅读他人代码
    • 阅读开源项目的代码,理解优秀代码的设计思路。
  4. 参加编程比赛
    • 比如 LeetCode 或 Codeforces,可以帮助你提升算法能力和C++的熟练度。

5. 保持耐心与兴趣
学习C++可能会面临以下困难:

  1. 复杂的语法:如模板、智能指针、多线程等。
  2. 调试困难:指针错误、内存泄漏、未定义行为可能让人头疼。

如何应对:

  • 将大问题拆解成小问题,逐步解决。
  • 不断重复基础知识,以加深理解。
  • 保持兴趣,尝试一些有趣的项目,比如写一个游戏、制作一个简单的图形程序。

小结
学习C++需要一个循序渐进的过程,从基础语法到面向对象编程,再到进阶的模板和并发编程,每一步都需要耐心和实践。通过充分利用学习资源、进行大量编码练习,以及挑战实际项目,你一定可以成为C++的高手。记住,学习的核心在于理解,而非死记硬背。

祝你学有所成,享受C++编程的乐趣!



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

相关文章:

  • Linux - 进程间通信(3)
  • 第三篇:模型压缩与量化技术——DeepSeek如何在边缘侧突破“小而强”的算力困局
  • 无用知识之:std::initializer_list的秘密
  • 使用朴素贝叶斯对自定义数据集进行分类
  • java后端之登录认证
  • 【数据结构】初识链表
  • C++11 多线程 锁与条件变量:mutex、lock_guard、unique_lock 和 condition_variable
  • 电控三周速成计划参考
  • 51c嵌入式~电路~合集25
  • GRE阅读双线阅读 --青山学堂GRE全程班 包括 阅读、数学、写作、填空、背单词
  • Math数字类
  • CH340G上传程序到ESP8266-01(S)模块
  • 大模型领域的Scaling Law的含义及作用
  • 7-4 西安距离
  • SAP HCM 回溯分析
  • 民法学学习笔记(个人向) Part.2
  • 元音字母(模拟)
  • 网络工程师 (16)侵权判断
  • DeepSeek- R1 原理介绍
  • Java中的泛型及其用途是什么?
  • windows linux常用基础命令
  • C++类定义中的关键字public 、protected 、private的详细介绍【定义类成员的访问权限属性和基类的成员的访问权限属性】
  • python:求解爱因斯坦场方程
  • Nginx 变量集合
  • 从零开始部署Dify:后端与前端服务完整指南
  • CSS Module 常用笔记