C语言实现单词逆序输出:双指针法解析
针对PTA平台上常见的句子单词逆序输出需求,本文提供一种基于C/C++语法的解题方案。该方法利用双指针从右向左扫描输入字符串,精准识别单词边界并逆向重组,适用于需要灵活控制内存分配的底层编程场景。
题目分析与核心逻辑
该题目的关键在于区分“单词”与“非单词字符”,并按相反顺序重新排列。由于题目通常对大小写字母及标点符号有特殊要求(如保留原样、不移动标点或仅按空格分割),最稳妥的方法是模拟栈的行为:先进后出。
虽然C++标准库提供了 `std::string` 和 `
环境准备与代码结构
程序主要依赖两个固定大小的字符数组作为输入缓冲区和输出缓冲区。为了处理可能的长句子,数组长度需根据题目限制设定(如500,001字节)。
- 输入读取:使用
getchar()循环读取直到换行符'\n',手动构建字符串结束符'\0'。 - 逆序遍历:设置索引
dest指向字符串末尾,向左递减。 - 单词识别与拷贝:当检测到单词起始位时,将其拷贝至输出数组,并在单词间插入空格。
第1步:读取原始字符串
入口为 stdin。动作是逐个获取字符并存入 arr1。
#include <iostream>
#include <cstring>
int main(void)
{
int a = 0;
char ch;
char arr1[500001]; // 输入缓冲
char arr2[500001]; // 输出缓冲
// 读取整行输入,包含空格
while ((ch = getchar()) != '\n')
{
arr1[a++] = ch;
}
arr1[a] = '\0'; // 手动添加字符串终止符
第2步:从右向左扫描并识别单词
这是算法的核心。我们需要找到每个单词的左边界。判断条件如下:
- 中间单词:当前字符是空格
' ',且下一个字符(右侧)不是空格也不是结束符。这意味着我们刚跨过上一个单词的空隙,找到了当前单词的右边界,而单词本身在左侧。 - 首个单词:如果当前索引为0,且第一个字符不是空格,说明这是句子的最后一个单词(即逆序后的第一个单词)。
int len = strlen(arr1);
int i = 0; // 输出数组索引
int dest = len - 1; // 当前扫描位置
while (dest >= 0)
{
// 判断是否到达单词开头
if (arr1[dest] == ' ' && arr1[dest + 1] != ' '&&arr1[dest+1]!='\0'
|| (dest == 0 && arr1[0] != ' '))
{
第3步:提取单词并填充输出
一旦确定单词范围,需要将字符从 arr1 拷贝到 arr2。注意:
1. 如果不是第一个写入 arr2 的单词,先写入一个空格分隔符。
2. 确定单词的左边界 last,若未处于头部,则 last = dest + 1;若处于头部且 arr1[0] 非空,则 last = 0。
3. 循环将字符填入 arr2,直到遇到空格或结束符。
if (i != 0) // 除了第一个单词,后续单词前加空格
arr2[i++] = ' ';
int last = dest + 1;
// 特殊处理:如果单词起始于字符串头部
if (dest == 0 && arr1[0] != ' ')
{
last = dest;
}
// 拷贝单词内容
while (arr1[last] != ' ' && arr1[last] != '\0')
{
arr2[i++] = arr1[last++];
}
}
dest--; // 继续向前扫描
}
arr2[i] = '\0'; // 输出字符串结束符
std::cout << arr2 << std::endl;
return 0;
}
关键点解析
上述代码中的逻辑判断 arr1[dest] == ' ' && arr1[dest + 1] != ' ' 用于定位单词的右邻空隙,确保不会连续复制多余空格。而 if(i!=0) arr2[i++] = ' '; 则是为了在重构的句子中维持单词间的单空格间隔,保证输出格式符合常规阅读习惯。
总结
这种“逆向扫描+区间拷贝”的方法避免了复杂的字符串切割函数调用,内存操作直观可控。理解其中的索引偏移与边界条件判定,是掌握C/C++低级字符串处理的关键。
以上就是C语言实现单词逆序输出的详细内容,更多关于C语言字符串操作与算法优化的资料请关注本站其它相关文章!
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













