7-9 说反话-加强版

文章讲述了如何使用C和C++编程语言解决一个问题,即给定一个英文句子,按单词顺序逆序输出。方法涉及遍历字符串、标记单词边界并按逆序输出。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

分数 20

全屏浏览题目

切换布局

作者 陈越

单位 浙江大学

给定一句英语,要求你编写程序,将句中所有单词的顺序颠倒输出。

输入格式:

测试输入包含一个测试用例,在一行内给出总长度不超过500 000的字符串。字符串由若干单词和若干空格组成,其中单词是由英文字母(大小写有区分)组成的字符串,单词之间用若干个空格分开。

输出格式:

每个测试用例的输出占一行,输出倒序后的句子,并且保证单词间只有1个空格。

输入样例:

Hello World   Here I Come

输出样例:

Come I Here World Hello

感谢杭州电子科技大学李卫明老师修正数据! 感谢浙江工业大学之江学院石洗凡老师修正测试点提示。

代码长度限制

16 KB

时间限制

300 ms

内存限制

64 MB

我的答案:

分析过程:

为了解决这个问题,我们需要首先确定每个单词的起始和结束位置,然后将这些单词按照逆序输出。

一种简单的方法是从后向前读取字符串,并记录单词的起始和结束位置。每当我们从一个非空格字符移动到一个空格字符时,我们就可以确定一个单词的结束位置,然后继续向前读取,直到遇到下一个非空格字符,该位置为单词的起始位置。现在我们可以输出从起始到结束位置的单词,并在输出下一个单词之前添加一个空格。

解题步骤:

  1. 读入字符串。
  2. 从字符串的尾部开始遍历。
  3. 如果找到一个非空格字符,标记为单词的结束位置。
  4. 继续向前遍历,直到找到一个空格字符或达到字符串的头部,此位置+1即为单词的起始位置。
  5. 输出从起始位置到结束位置的单词。
  6. 如果当前位置不是字符串的起始位置,则输出一个空格,并继续从上一步的起始位置-1继续查找下一个单词。
  7. 重复步骤3-6直到遍历完整个字符串。

C语言:

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

int main() {
    char str[500001];
    gets(str);  // 读入字符串
    int length = strlen(str);  // 获取字符串长度
    int end, start, isFirst = 1;

    for (end = length - 1; end >= 0;) {
        if (str[end] != ' ') {  // 找到单词的结束位置
            start = end;
            while (start >= 0 && str[start] != ' ') {  // 找到单词的起始位置
                start--;
            }
            start++;

            // 输出单词
            if (isFirst) {
                isFirst = 0;
            } else {
                printf(" ");
            }
            for (int i = start; i <= end; i++) {
                printf("%c", str[i]);
            }
            end = start - 2;
        } else {
            end--;
        }
    }

    return 0;
}

C++:

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

int main() {
    string str;
    getline(cin, str);  // 读入字符串
    int end, start, length = str.length();
    bool isFirst = true;

    for (end = length - 1; end >= 0;) {
        if (str[end] != ' ') {
            start = end;
            while (start >= 0 && str[start] != ' ') {
                start--;
            }
            start++;

            // 输出单词
            if (isFirst) {
                isFirst = false;
            } else {
                cout << " ";
            }
            for (int i = start; i <= end; i++) {
                cout << str[i];
            }
            end = start - 2;
        } else {
            end--;
        }
    }

    return 0;
}

这两种解决方案基本上是相同的,但是C++版本使用了C++标准库中的字符串处理函数,而C版本使用了C标准库中的函数。

我将逐一解析每个步骤:

1. **读入字符串。**
   - 首先,我们需要拥有一个字符串才能开始处理。这一步是获取输入。

2. **从字符串的尾部开始遍历。**
   - 为何从尾部开始而不是头部呢?因为我们的目标是将句子的单词顺序反转。从尾部开始遍历可以使我们首先找到最后的单词,这样在输出时,它就变成了第一个单词。

3. **如果找到一个非空格字符,标记为单词的结束位置。**
   - 为何是非空格字符?因为英文单词是由字母组成,并用空格分隔。当我们从后向前遍历并遇到第一个非空格字符时,我们知道我们已经找到了一个单词的结束位置。

4. **继续向前遍历,直到找到一个空格字符或达到字符串的头部,此位置+1即为单词的起始位置。**
   - 既然我们找到了单词的结束,下一步自然是找到它的开始。从当前位置继续向前遍历,直到遇到一个空格(这意味着单词结束了)或字符串的开始位置(对于第一个单词来说)。记住,我们已经确定了单词的结束位置,所以我们知道单词的起始和结束位置之间的字符构成了这个单词。

5. **输出从起始位置到结束位置的单词。**
   - 有了单词的起始和结束位置,我们可以直接输出它。

6. **如果当前位置不是字符串的起始位置,则输出一个空格,并继续从上一步的起始位置-1继续查找下一个单词。**
   - 这步确保了单词间只有一个空格。因为我们在输出一个单词后可能有多个空格(例如输入字符串有多个连续的空格),我们跳过这些额外的空格并找到下一个单词的结束位置。

7. **重复步骤3-6直到遍历完整个字符串。**
   - 我们将重复这个过程,直到我们处理了字符串中的每一个字符,从而保证了每个单词都被反向输出。

总结:这种方法的关键在于它从尾到头遍历字符串并使用空格作为单词分隔符。在输出时,这确保了我们首先输出的是最后一个单词,然后是倒数第二个单词,以此类推,从而达到了反转单词顺序的目的。

总结:

这道题目的主题是“说反话”,但它实际上涉及了许多基础的编程和数据处理技能。通过这题,我们可以学到以下几点:

1. **字符串操作**:如何遍历、如何标记单词的开始和结束,以及如何根据标记输出子串。

2. **逆序处理**:对数据进行反向处理是一个常见的编程问题,不仅仅局限于字符串。

3. **特定字符的定位与跳过**:在这个场景中,是空格作为分隔符。但在其他上下文中,我们可能需要跳过逗号、制表符或其他字符。

4. **边界条件的处理**:如何处理字符串的开始和结束、如何处理多余的空格等,都是需要考虑的边界条件。

5. **优化处理**:尽管这道题的初级解决方案是从尾到头遍历字符串,但还有其他方法,例如分割字符串并存储在数组或其他数据结构中,然后逆序输出。选择哪种方法取决于具体的需求和约束。

6. **实际应用的启示**:在真实世界的应用中,我们可能需要处理各种文本数据,如日志文件、用户输入等。学会如何有效地处理字符串和文本是任何编程语言中的一个重要技能。

总的来说,这道题目提供了对字符串处理的实践经验,并强调了为何这种能力在实际应用编程中是如此重要。

 

### Java 中实现加强版反话功能的代码示例 在 Java 编程中,可以通过字符串操作来实现一种“反话”功能。这种功能通常涉及将入字符串反转或者按照特定逻辑重新排列字符顺序。下面是一个简单的例子,展示如何通过递归或迭代方式实现字符串反转的功能。 #### 方法一:使用 StringBuilder 的 reverse 方法 Java 提供了一个内置工具 `StringBuilder`,它有一个方便的方法 `reverse()` 来快速反转字符串的内容。 ```java public class ReverseString { public static String reverse(String input) { if (input == null || input.isEmpty()) { return input; } return new StringBuilder(input).reverse().toString(); } public static void main(String[] args) { String original = "你好,世界!"; String reversed = reverse(original); System.out.println("原始字符串: " + original); // 原始字符串: 你好,世界! System.out.println("反转后的字符串: " + reversed); // 反转后的字符串: !界世,好你 } } ``` 此方法简单高效,适合处理基本需求[^1]。 --- #### 方法二:手动实现字符串反转(迭代法) 如果不希望依赖于库函数,则可以采用循环的方式逐个交换字符位置: ```java public class ManualReverse { public static String reverse(String input) { char[] array = input.toCharArray(); int left = 0, right = array.length - 1; while (left < right) { // Swap characters at the two ends char temp = array[left]; array[left] = array[right]; array[right] = temp; left++; right--; } return new String(array); } public static void main(String[] args) { String original = "Hello World"; String reversed = reverse(original); System.out.println("Original string: " + original); // Original string: Hello World System.out.println("Reversed string: " + reversed); // Reversed string: dlroW olleH } } ``` 该算法的时间复杂度为 O(n),空间复杂度为 O(1)[^2]。 --- #### 方法三:递归实现字符串反转 对于更复杂的场景,比如嵌套结构的数据反转,可以考虑递归来解决问题。以下是基于递归的字符串反转实现: ```java public class RecursiveReverse { public static String reverse(String str) { if ((null == str) || (str.length() <= 1)) { return str; } return reverse(str.substring(1)) + str.charAt(0); } public static void main(String[] args) { String original = "Recursion Example"; String reversed = reverse(original); System.out.println("Original string: " + original); // Original string: Recursion Example System.out.println("Reversed string: " + reversed); // Reversed string: elpmaxE noisucER } } ``` 递归方法虽然简洁优雅,但在大规模数据下可能会遇到栈溢出的风险[^3]。 --- ### 加强版反话功能扩展 如果需要进一步增强反话功能,例如支持单词级别的翻转而不是整个句子的整体翻转,可以尝试如下代码: ```java import java.util.*; public class WordLevelReverse { public static String reverseWords(String sentence) { List<String> words = Arrays.asList(sentence.split(" ")); Collections.reverse(words); return String.join(" ", words); } public static void main(String[] args) { String sentence = "今天天气真不错"; String result = reverseWords(sentence); System.out.println("原句: " + sentence); // 原句: 今天天气真不错 System.out.println("反序后: " + result); // 反序后: 不错真气天今 } } ``` 这段程序会先按空格分割句子成多个部分,再逐一逆向组合这些片段形成最终结果[^4]。 --- ### 总结 以上介绍了几种不同的字符串反转技术及其应用场景。无论是基础版本还是高级定制化方案都可以满足实际开发中的多样化需求。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

夏驰和徐策

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值