【C++】B2122 单词翻转

发布于:2025-02-10 ⋅ 阅读:(73) ⋅ 点赞:(0)

在这里插入图片描述

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


在这里插入图片描述


💯前言

  • 在计算机科学中,字符串处理是一个非常基础且常见的任务。本题主要围绕如何将一个句子中的每个单词反转来进行练习。这个问题不仅考察了对字符串操作的理解,还涉及了不同的解决方法。在本篇文章中,我们将详细探讨我自己的做法、老师提出的两种做法,并深入讲解C++中 reverse 函数的使用,最后通过对比和拓展分析这些方法的优缺点。
    C++ 参考手册
    在这里插入图片描述

💯题目描述

B2122 单词翻转
在这里插入图片描述

小明同学写单词的时候喜欢反着写,比如 hello 他会写成 olleh。给出小明同学写的一个句子,请你将所有的单词复原。

输入格式

共一行,一个字符串表示句子,单词之间以空格分隔。

输出格式

每个单词一行。

样例 #1

样例输入 #1

olleh dlrow

样例输出 #1

hello
world

💯一、我的做法

代码实现:

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

int main()
{
    string s;
    while(cin >> s)
    {
        for(int i = s.size() - 1; i >= 0; i--)
        {
            cout << s[i];
        }
        cout << endl;
    }
    
    return 0;
}

代码解析

在这个实现中,我选择了通过手动反转每个单词的字符来恢复正确的单词顺序。

  1. 变量声明

    • string s;:声明一个字符串变量 s 用于存储从输入中读取的每个单词。
  2. 读取输入

    • while(cin >> s):使用 cin >> s 读取一个单词,直到没有更多输入。
  3. 反转每个单词

    • for(int i = s.size() - 1; i >= 0; i--):我们使用一个从单词末尾到开头的 for 循环,通过访问每个字符并逆序输出,来实现反转操作。
  4. 输出每个单词

    • cout << s[i];:逐个输出反转后的字符。
  5. 换行

    • 每个单词输出后,使用 cout << endl; 换行,确保每个单词占一行。

思路分析

这段代码通过遍历每个字符并从末尾到开头进行输出来实现反转。通过这种手动操作字符的方式,能够准确地完成任务。它的优点是直接且易于理解,但缺点是代码稍显冗长,且没有利用C++标准库提供的便捷工具。


💯二、老师的第一种做法

老师给出的第一种做法是通过手动交换字符串中的字符来反转单词。下面是老师的代码实现:

代码实现:

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

int main()
{
    string str;
    while(cin >> str)
    {
        int left = 0;
        int right = str.size() - 1;
        while(left < right)
        {
            char tmp = str[left];
            str[left] = str[right];
            str[right] = tmp;
            left++;
            right--;
        }
        cout << str << endl;
    }
    
    return 0;
}

代码解析

老师的做法同样采用了字符交换的方式来反转每个单词。其关键点在于通过两个指针从字符串的两端向中间移动,交换字符,直到完成反转。

  1. 初始化两个指针

    • int left = 0; int right = str.size() - 1;leftright 分别是指向字符串开始和结束的两个指针。
  2. 交换字符

    • char tmp = str[left]; str[left] = str[right]; str[right] = tmp;:通过一个临时变量 tmp 来交换 str[left]str[right]
  3. 逐步移动指针

    • left++right--:交换后,left 指针向右移动,right 指针向左移动,逐步将字符串反转。
  4. 输出反转后的字符串

    • cout << str << endl;:输出反转后的单词。

思路分析

老师的做法通过交换字符来反转字符串,使用了双指针的技巧,这种方法比我的做法更具效率,因为它只需要一次遍历,每次只交换两个字符。相比手动逐个输出字符,这种方法更符合常见的反转思路,代码更简洁。


💯三、C++ reverse 函数介绍

在C++标准库中,提供了一个名为 reverse 的函数,它可以轻松地反转一个容器(例如字符串、数组等)的元素顺序。该函数位于 <algorithm> 头文件中,使用时非常方便。

reverse 函数原型:

void reverse(BidirectionalIterator first, BidirectionalIterator last);
  • first:指向待反转区间的起始元素的迭代器。
  • last:指向待反转区间的结束元素的迭代器。

该函数会反转区间 [first, last) 中的元素。

示例:

string s = "abcd";
reverse(s.begin(), s.end());
cout << s << endl; // 输出 "dcba"

优点

  • 简洁:C++ reverse 函数将反转操作封装得非常简洁。只需调用一次 reverse,就能完成字符串或数组的反转,代码更加清晰易懂。
  • 高效reverse 内部实现通常采用类似于双指针交换的方式,性能非常高。

💯四、老师的第二种做法:使用 reverse 函数

老师的第二种做法直接利用了 C++ STL 中的 reverse 函数,这使得反转操作变得更加简便。

代码实现:

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

int main()
{
    string str;
    while (cin >> str)
    {
        reverse(str.begin(), str.end());
        cout << str << endl;
    }
    return 0;
}

代码解析

这段代码通过 reverse 函数反转字符串:

  1. 使用 reverse 函数

    • reverse(str.begin(), str.end());:直接使用 reverse 函数来反转字符串 str
  2. 输出反转后的字符串

    • cout << str << endl;:输出每个反转后的单词,并换行。

思路分析

这种做法通过使用 C++ STL 中的现成函数来简化代码。reverse 函数提供了高效且简洁的反转操作,比手动交换字符或逐个输出字符的方法要简单得多。


💯五、对比分析

  1. 我的做法

    • 优点:代码简单,容易理解,适用于初学者。
    • 缺点:冗长,效率较低,特别是手动反转每个字符时,不够高效。
  2. 老师的第一种做法

    • 优点:通过双指针交换字符,比手动输出字符更高效。
    • 缺点:代码较为复杂,理解起来可能稍微困难。
  3. 老师的第二种做法

    • 优点:使用 reverse 函数,代码最简洁,符合C++的标准库优势,效率高。
    • 缺点:可能需要对 reverse 函数有一定的了解。

💯六、拓展

除了 reverse 函数外,我们还可以用其他方式来处理字符串或数组的反转操作:

  1. 利用栈:将字符压入栈中,然后从栈中弹出字符来实现反转。
  2. 递归:通过递归函数逐步将字符串或数组的字符进行反转。

💯小结

通过对比不同的做法,我们可以看到,C++提供了多种有效的反转策略。通过手动字符交换、使用 reverse 函数,甚至使用 STL 容器的其他方法,我们可以灵活地选择最适合问题需求的解决方案。在实际开发中,选择合适的工具和方法,不仅能提高代码的可读性,还能提高程序的效率。


在这里插入图片描述


学习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++编程的乐趣!


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

最开始的解法不通过

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

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

在这里插入图片描述

老师优化后通过

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

int main()
{
    string s;
    getline(cin, s);
    int i = 0;
    int index = 0;
    for (i = 0; i < s.size() - 1; i++)
    {
        if (s[i] == ' ')
        {
            for (int j = i - 1; j >= index; j--)
            {
                cout << s[j];
            }
            cout << endl;
            index = i + 1;
        }
        else if (i == s.size() - 2)
        {
            for (int j = i; j >= index; j--)
            {
                cout << s[j];
            }
            cout << endl;
        }
    }
    return 0;
}

网站公告

今日签到

点亮在社区的每一天
去签到