倒置字符串

题目链接

倒置字符串

题目描述与示例

将一句话的单词进行倒置,标点不倒置。比如 I like beijing. 经过函数后变为:beijing. like I

输入描述

每个测试输入包含1个测试用例: I like beijing. 输入用例长度不超过100

输出描述

依次输出倒置之后的字符串,以空格分割

示例

输入:

I like beijing.

输出:

beijing. like I

解题思路

题目分析

题目很简单,简单来说就是将单词+上标点符号逆序输出

个人思路

虽然我的解法很呆,但是好歹能跑过(也只能这么安慰一下了)

  1. 遍历字符串,遇到非空格字符停下,寻找最近的空格位置。(说简单一点就是确定单词的区间)
  2. 通过找到的区间构造一个string保存下来插入到一个vector的对象里面
  3. 逆序输出这个vector对象

我感觉我这个思路还是挺简单的。。。。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-c8AyrrCG-1653106602935)(C:\Users\lwz\AppData\Roaming\Typora\typora-user-images\image-20220519184834463.png)]

1-2大致就完成这样,然后逆序输出就可以了。

代码展示

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

//找到空格所在的下标
int Index(const string &s,size_t begin)
{
    size_t end=begin;
    for(;end!=s.size();end++)
    {
        if(s[end]==' ')
        break;
    }
    return end;
}

int main()
{
    string s1;
    getline(cin,s1);
    vector<string> A;
    for(size_t i=0;i<=s1.size();i++)
    {
        //不是空格就开始寻找空格的下标
        if(s1[i]!=' ')
        {
            size_t j=Index(s1,i);
            //通过开始的位置和空格的位置构造一个string对象保存单词信息
            string tmp(s1,i,j-i);
            i=j;
            //把string对象插入到A中
            A.push_back(tmp);
        }
    }
    //利用反向迭代器输出
    //也可以先逆置了再直接输出
    auto it=A.rbegin();
    while(it!=A.rend())
    {
        cout<<*it<<" ";
        it++;
    }
    return 0;
}

题解

思路:

  1. 整体逆置
  2. 单词逆置

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QOQ29ErL-1653106602937)(C:\Users\lwz\AppData\Roaming\Typora\typora-user-images\image-20220519190119216.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-T0Fmdltr-1653106602937)(C:\Users\lwz\AppData\Roaming\Typora\typora-user-images\image-20220519190321512.png)]

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

int main()
{
    string s;
    getline(cin,s);
    //进行整体的逆置 ->gnijieb ekil I
    reverse(s.begin(),s.end());

    auto start = s.begin();

    while(start != s.end()) 
    {
        auto end = start;
        while(end != s.end() && *end != ' ') 
        {
            end++;
        }
        //走到这里说明end要么走到尾巴上了,要么*end为空格了
        //局部单词逆置
        reverse(start,end);
        //*end为空格,start就直接到end的下一个位置
        if(end != s.end()) 
        {
            start = end+1;
        }
        //end走到头,直接start=end即可退出循环
        else
        {
            start = end;
        }
    }
    cout<<s<<endl;
    return 0;
}

上面就是题解的常规解法了,但是我在看题解的时候又看到了一种偏激的解法,我愿称之为巨佬,话不多说,直接给上代码再讲原理:

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

int main()
{
    string s1, s2;
    cin >> s2;
    while (cin >> s1)
        s2 = s1  + " " + s2;
    cout << s2 << endl;
    return 0;
}

没错,就是这么几行代码就可以跑过了,原理其实也不复杂,我们都知道cin是以空格为分割符,我们以示例的I like beijing.为例:

当代码运行到 cin>>s2;是输入I like beijing.此时s2只获取到了I一个字符就被空格给断开了,程序直接到了while,再给s1赋值like,又令s2 = like + " " + I,此时s2中就成了“like I”,同理while循环继续执行,s1获取到beijing.再执行s2 = “beijing.” + " " + “like I”,这个时候s2就成了“beijing. like I”完成了此题。

以上就是我对这个解法的理解了,不得不说确实是超乎常人的思维了(至少我没想到还能这么玩,感觉我就是来凑数的)。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值