1233 : C语言/C++单词倒置(ZZNUOJ)⭐⭐

 

题目描述(难度⭐⭐)

最近birdfly收到了女友的几份信件,为了只要他俩知道信件的秘密,女友把信件里的每个单词都倒置了。这样只有birdfly将它们倒置过来才能明白女友的心思了。为此birdfly还特意请你编写程序帮他解决一下这个问题。 
简单起见假定每封信只包含英文单词和空格,每两个单词之间有一个空格。且长度不超过100,每个单词长度不超过50。 

输入

输入有多组样例,每组样例输入一行英文(单词和空格)。

输出

对于每组实例输出单词倒置后的结果。每组实例输出占一行。

样例输入

复制
I ma yppah yadot
oT eb ro ton ot eb
I tnaw ot niw eht ecitcarp tsetnoc

样例输出

复制
I am happy today
To be or not to be
I want to win the practice contest

思路:使用栈来逆序输出每行输入中的每个单词,同时保持单词之间的空格不变,处理多实例输入时,利用 while (getline(cin, line)) 循环读取每一行输入,直到输入结束。 

        了解栈(stack)点此数据结构知识点-CSDN博客

         同类题目:C++STACK字符串内部单词反转顺序输出⭐⭐-CSDN博客

代码1详解

处理多实例输入:

◦  使用 while (getline(cin, line)) 循环读取每一行输入,直到输入结束。

                了解 getline(cin, line)点此C++函数——getline(cin, line)-CSDN博客

◦  每读取一行输入,调用 solve(line) 函数处理该行输入。  

◦  getline(cin, line) 会读取一行输入并存储在字符串 line 中,直到遇到换行符 '\n' 为止。  

◦  如果输入结束(例如用户输入 EOF,即 Ctrl+D(Linux/Mac)或 Ctrl+Z(Windows)),      getline 会返回 false,循环结束。 

处理单行输入:

◦  使用一个栈 stack<char> word 来存储每个单词的字符。

 ◦  遍历输入的字符串 line,对于每个字符 ch:

                ■  如果 ch 是空格,将栈中的字符依次弹出并输出,然后输出一个空格。  

                ■  如果 ch 是其他字符,将其压入栈中。    

◦  处理完所有字符后,将栈中剩余的字符依次弹出并输出,以处理最后一个单词。  

◦  最后输出一个换行符。

法一(使用c++的数据结构栈)

详细代码

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

// 逆序输出每行输入中的每个单词,同时保持单词之间的空格不变
void solve(string line) {
    stack<char> word; // 用于存储每个单词的字符
    for (char ch : line) { // 遍历输入的字符串
        if (ch == ' ') { // 遇到空格
            while (!word.empty()) { // 逆序输出当前单词
                cout << word.top();
                word.pop();
            }
            cout << " "; // 输出空格
        } else {
            word.push(ch); // 将字符压入栈中
        }
    }
    // 处理最后一个单词
    while (!word.empty()) {
        cout << word.top();
        word.pop();
    }
    cout << endl; // 输出换行符
} 

int main() {
    ios::sync_with_stdio(false); // 优化输入输出
    cin.tie(nullptr); // 优化输入输出
    string line;
    while (getline(cin, line)) { // 读取每一行输入,直到输入结束
        solve(line); // 处理每一行输入
    }
}

法二(C语言字符数组,自定义reverse反转函数)

用这个方法需要了解字符串输出格式%.*s 

点这里了解:%.*s——C语言中printf 函数中的一种格式化输出方式-CSDN博客

版本一(定义全局变量,避开指针传参) 

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

/*
%%%%%%%%%%%%%%
 /\_/\  /\_/\ 
(* . *)(+ . +)	
 > # <  > $ <
%%%%%%%%%%%%%%
*/

// 声明一个全局字符数组,用于存储输入的字符串
char str[101];

// 反转字符串 str 中从索引 m 到 n 的部分
void reverse(int m, int n) {
    for (int i = 0; i < (n - m + 1) / 2; i++) {
        // 临时变量,用于交换
        char ch = str[m + i];
        // 交换前半部分的字符
        str[m + i] = str[n - i];
        // 交换后半部分的字符
        str[n - i] = ch;
    } 
}

// 处理输入的字符串,将每个单词进行反转
void solve() {
    int sr = 0, ed = 0;  // sr 和 ed 分别表示当前单词的起始和结束位置
    for (int i = 0; str[i] != '\0'; i++) {  // 遍历字符串,直到遇到空字符 '\0'
        if (str[i] == ' ') {  // 如果遇到空格,表示一个单词结束
            // 反转当前单词
            reverse(sr, ed - 1);
            // 输出反转后的单词,单词长度为 ed - sr
            printf("%.*s ", ed - sr, str + sr);
            // 更新起始位置为下一个单词的开始
            sr = i + 1;
            // 更新结束位置
            ed = i + 1;
        } else {
            // 如果不是空格,结束位置向后移动
            ed++;
        }
    }
    // 处理最后一个单词
    reverse(sr, ed - 1);
    // 输出反转后的最后一个单词,单词长度为 ed - sr
    printf("%.*s\n", ed - sr, str + sr);
}

int main() {
    // 读取每一行输入,直到文件结束符
    while (gets(str) != NULL) {
        // 处理每一行输入
        solve();
    }
    // 程序结束
    return 0;   
}

版本二(使用指针传参) 

/*
%%%%%%%%%%%%%%
 /\_/\  /\_/\ 
(* . *)(+ . +)	
 > # <  > $ <
%%%%%%%%%%%%%%
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

// 反转字符串 str 中从索引 m 到 n 的部分
void reverse(char *str, int m, int n) {
    for (int i = 0; i < (n - m + 1) / 2; i++) {
        char ch = str[m + i];  // 临时变量,用于交换
        str[m + i] = str[n - i];  // 交换前半部分的字符
        str[n - i] = ch;  // 交换后半部分的字符
    } 
}

// 处理输入的字符串,将每个单词进行反转
void solve(char *str) {
    int sr = 0, ed = 0;  // sr 和 ed 分别表示当前单词的起始和结束位置
    for (int i = 0; str[i] != '\0'; i++) {  // 遍历字符串,直到遇到空字符 '\0'
        if (str[i] == ' ') {  // 如果遇到空格,表示一个单词结束
            reverse(str, sr, ed - 1);  // 反转当前单词
            printf("%.*s ", ed - sr, str + sr);  // 输出反转后的单词
            sr = i + 1;  // 更新起始位置为下一个单词的开始
            ed = i + 1;  // 更新结束位置
        } else {
            ed++;  // 如果不是空格,结束位置向后移动
        }
    }
    // 处理最后一个单词
    reverse(str, sr, ed - 1);  // 反转最后一个单词
    printf("%.*s\n", ed - sr, str + sr);  // 输出反转后的最后一个单词
}

int main() {
    char str[101];  // 声明一个字符数组,用于存储输入的字符串
    while (gets(str) != NULL) {  // 读取每一行输入,直到文件结束符
        solve(str);  // 处理每一行输入
    }
    return 0;  // 程序结束
}

法三(C++字符串,使用自带的reverse函数)

了解 reverse函数点击C++知识点_c++ std::reverse-CSDN博客


用这个方法需要了解字符串输出格式%.*s 

点这里了解:%.*s——C语言中printf 函数中的一种格式化输出方式-CSDN博客

#include<bits/stdc++.h>
using namespace std;

void solve(string& line) {
    int st = 0, ed = 0; // st 和 ed 分别表示当前单词的起始和结束位置
    for (auto ch : line) { // 遍历字符串中的每个字符
        if (ch == ' ') { // 如果遇到空格,表示一个单词结束
            reverse(line.begin() + st, line.begin() + ed); // 反转当前单词
            printf("%.*s ", ed - st, line.begin() + st); // 输出反转后的单词
            st = ed + 1; // 更新起始位置为下一个单词的开始
            ed++; // 结束位置向后移动
        } else {
            ed++; // 如果不是空格,结束位置向后移动
        }
    }
    reverse(line.begin() + st, line.begin() + ed); // 处理最后一个单词
    printf("%.*s\n", ed - st, line.begin() + st); // 输出反转后的最后一个单词
} 

int main() {
    ios::sync_with_stdio(false); // 禁用同步,提高输入输出效率
    cin.tie(nullptr); // 解绑 cin 和 cout,提高输入输出效率
    string line;
    while (getline(cin, line)) { // 读取每一行输入
        solve(line); // 处理每一行输入
    }
}

详细解释

  1. 包含头文件和命名空间

    • 包含 C++ 标准库的所有头文件,方便使用各种功能。

    • 使用标准命名空间,避免每次调用标准库函数时都需要前缀 std::

  2. 定义 solve 函数

    • 初始化变量

      • sted 分别表示当前单词的起始和结束位置。

    • 遍历字符串

    • 处理空格

      • 如果当前字符 ch 是空格,表示一个单词结束。

      • 使用 reverse 函数反转当前单词。

      • 使用 printf 输出反转后的单词。

      • 更新起始位置 st 为下一个单词的开始。

      • 结束位置 ed 向后移动一位。

    • 处理非空格字符

      • 如果当前字符 ch 不是空格,结束位置 ed 向后移动一位。

    • 处理最后一个单词

      • 循环结束后,处理最后一个单词。

      • 使用 reverse 函数反转最后一个单词。

      • 使用 printf 输出反转后的最后一个单词。

      • 输出换行符。

  3. 定义 main 函数

    • 优化输入输出

      • 禁用 C++ 和 C 输入输出流的同步,提高输入输出效率。

      • 解绑 cincout,进一步提高输入输出效率。

    • 读取输入

      • 声明一个字符串变量 line,用于存储每一行输入。

      • 使用 getline 函数读取每一行输入,直到文件结束。

      • 调用 solve 函数处理每一行输入。

 

收藏加关注,观看不迷路 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值