开发者

C++反转字符串中单词的字符顺序的两种方法

目录
  • 问题描述
  • 基于快慢指针的解法
  • 基于索引的解法
  • 两种方法的比较

问题描述

在处理字符串相关的问题时,反转字符串中每个单词的字符顺序是一个常见的任务,同时要保证空格和单词的初始顺序不变。

给定一个字符串 s ,你需要反转字符串中每个单词的字符顺序,同时仍保留空格和单词的初始顺序。

  • s 包含可打印的 ASCII 字符。
  • s 不包含任何开头或结尾空格。
  • s 里 至少 有一个词。
  • s 中的所有单词都用一个空格隔开。

下面我们将详细介绍两种解决该问题的方法,包括其解题思路和具体实现细节。

基于快慢指针的解法

1. 解题思路

快慢指针是一种常用的技巧,在本题中,快指针用于遍历字符串,慢指针用于标记每个单词的起始位置。

当快指针遇到空格时,就表示一个单词已经遍历完,此时可以对慢指针到快指针之间的字符进行反转。

遍历完整个字符串后,还需要对最后一个单词进行反转,因为最后一个单词后面没有空格来触发反转操作。同时,这也对只要一个单词的情况进行了处理

2. 代码实现

class Solution {
public:
    string reverseWords(string s) //快慢指针解法
    {
        string::iterator fast = s.begin();
        string::iterator slow = s.begin();
 
        while( fast != s.end() )//快指针走完就结束
        {
            if(*fast==' ') //快指针走到空格位置停下,反转该部分字母
            {
                reverse(slow,fast);
                slow = fast+1;
            }
            ++fast;
        }
        reverse(slow,fast);//出循环时,慢指针留在最后一个单词的第一个字母
                           //快指针在\0位置,还需要反转一次
        //同时可以对只要一个单词的string处理
        return s;
 
    }
};

3. 代码细节分析

  • 指针初始化:首先定义了快指针 fast 和慢指针 slow,并将它们都初始化为字符串 s 的起始位置 s.begin()。
  • 遍历字符串:通过 while 循环,只要快指针 fast 没有到达字符串末尾 s.end(),就继续循环。
  • 单词反转:当快指针 fast 指向的字符为空格时,说明一个单词已经遍历完,此时调用 reverse 函数将慢指针 slow 到快指针 fast 之间的字符进行反转。然后将慢指针 slow 移动到下一个单词的起始位置,即 fast + 1。
  • 最后一个单词处理:循环结束后,慢指针 slow 停留在最后一个单词的起始位置,快指针 fast 指向字符串末尾的下一个位置(即 \0 的位置),此时再调用一次 reverse 函数对最后一个单词进行反转。
  • 返回结果:最后返回反转后的字符串 s。

基于索引的解法

1. 解题思路

这种方法使用索引来遍历字符串,通过一个变量记录每个单词的起始位置,当遇到空格或者字符串结束时,对当前单词进行反转。

2. 代码实现

#include <IOStream>
#include <string>
QzObie#include <algorithm>
 
class Solution {
public:
    string reverseWords(string s) {
        int start = 0; // 慢指针,标记每个单词的起始位置
        for (int end = 0; end <= s.length(); ++end) {
            // 当遇到空格或者字符串结束时,反转当前单词
            if (end == s.length() || s[end] == ' ') {
                // 反转从 start 到 end - 1 的字符
                std::reverse(s.begin() + start, s.begin() + end);
                // 更新慢指针到下一个单词的起始位置
                start = end + 1;
            }
        }
        return s;
    }
};

3. 代码细节分析

  • 起始位置初始化:定义变量 start 来记录每个单词的起始位置,初始化为 0。
  • 遍历字符串:通过 for 循环,使用变量 end 遍历字符串 s,循环条件为 end <= s.length(),这样可以确保在字符串结束时也能处理最后一个单词。
  • 单词反转:当 end 等于字符串的长度 s.length() 或者 s[end] 为空格时,说明一个单词已经遍历完,此时调用 std::reverse 函数将从 s.begin()编程客栈 + start 到 s.begin() + end 的字符进行反转。
  • 更新起始位置:反转完当前单词后,将 start 更新为 end + 1,即下一个单词的起始位置。
  • 返回结果:循环结束后,返回反转后的js字符串 s。

两种方法的比QzObie

  • 时间复杂度:两种方法的时间复杂度都是 O(n),其中 n 是字符串的长度,因为都需要遍历字符串一次,并且每个字符最多被反转一次。
  • 空间复杂度:两种方法的空间复杂度都是 O(1),因为都只使用了常数级的额外空间。
  • 代码可读性:基于索引的方法代码相对更加简洁,使用索引来处理字符串更加直观,而基于快慢指针的方法需要对指针的操作有较好的理解

通过以上两种方法的详细介绍,我们可以根据具体的需求和个人习惯选择合适的方法来解决反转字符串中单词字符顺序的问题。

到此这篇关于C++反转字符串中单词的字符顺序的两种方法的文章就介绍到这了,更多相关C++反转单词字符顺序内容请搜索编程客栈(www.devze.com)以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程客php栈(www.devze.com)!

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新开发

开发排行榜