HJ13 句子逆序

246 阅读2分钟

Day11 2023/01/18

题目链接

难度:简单

题目

将一个英文语句以单词为单位逆序排放,例如“I am a boy”,逆序排放后为“boy a am I”,所有单词之间用一个空格隔开,语句中除了英文字母外,不再包含其他字符,数据范围:输入的字符串长度满足:1 ≤n ≤ 1000

输入描述:

输入一个英文语句,每个单词用空格隔开。保证输入只包含空格和字母。

输出描述:

得到逆序的句子

示例

输入:I am a boy
输出:boy a am I

思路一


首先将字符串整体反转,然后以空格为界,再反转各个单词。
原字符串:i am a boy
第一次反转:yob a ma i
第二次反转:boy a am i

思路二


利用cin流遇空格就结束,因此输入的时候单词和单词之间就形成自然分割了,然后反向拼接字符串,然后输出即可。

思路三


利用栈的先进后出,同方法一一样的方式分割字符串并进栈,然后再出栈即可,如图所示:

47F8C17FA3484E6A55A3A0341947EDCD.gif

关键点


  • 理解思路一中,是如何分割字符串的,利用的是我们熟悉的双指针的方式。

算法实现


c++代码实现1-两次反转

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

 //方法一:两次反转
int main () {
    cout << "请输入字符串:";
    string str;
    getline(cin, str); //获取字符串
    int len = str.length(); //字符串长度
    reverse(str.begin(), str.end()); //先整体反转第一遍
    for (int i = 0; i < len; i++) {
        int j = i; //对每个单词循环前都让i和j指向同一个位置
        while (j < len && str[j] != ' ') j++; //以空格确定每个单词
        reverse(str.begin() + i, str.begin() + j);
        i = j; //指向下一个单词的前一个位置
    }
    cout << "逆序之后:" << str << endl;
}
  • 时间复杂度 O(n)O(n) --- 遍历整个字符串, n为字符串长度
  • 空间复杂度 O(1)O(1) --- 字符串为必要空间,无额外空间

c++代码实现2-输入时反向拼接

#include<iostream>
#include<string>
#include<algorithm>
#include <stack>
using namespace std;
 
//方法二:输入时反向拼接
int main(){
    string s, temp;
    while(cin >> temp){ //输入字符串
        temp += " " + s; //每个单词加在字符串前面
        s = temp;
        if(cin.get() == '\n') break;
    }
    cout << s << endl;
    return 0;
}
  • 时间复杂度 O(n)O(n) --- 遍历整个字符串, n为字符串长度
  • 空间复杂度 O(1)O(1) --- 字符串为必要空间,无额外空间

c++代码实现3-分割字符串+栈

#include<iostream>
#include<string>
#include<algorithm>
#include <stack>
using namespace std;
 
 //方法三:栈
int main(){
    cout << "请输入字符串:";
    string s;
    getline(cin, s); //获取字符串
    int n = s.length();
    stack<string> st;
    for(int i = 0; i < n; i++){ //遍历字符串,找到单词并入栈
        int j = i;
        while(j < n && s[j] != ' ')  //以空格为界,分割单词
                j++;
            st.push(s.substr(i, j - i));  //单词进栈
            i = j;
    }
     cout << "逆序之后:";
    while(!st.empty()){   //栈遵循先进后处,单词顺序是反的
            
            cout << st.top() << " ";
            st.pop();
    }
    return 0;
}
  • 时间复杂度 O(n)O(n) --- 遍历整个字符串, n为字符串长度
  • 空间复杂度 O(n)O(n) --- 栈空最坏情况下长度为n

总结

  • 有时可以利用常用数据结构的特点去解题。

  • 可以利用方法二中分割字符串的方式和方法三中输出的方式,两者结合代码可以更加简洁。