C++实现句子单词顺序翻转的三种编程思路
在C++开发中,解决“输入一个英文句子,翻转句子中单词的顺序”这一经典问题,通常采用先整体逆序、再局部逆序的两步走策略。本文将展示如何通过指针操作和循环遍历,用不同代码结构实现这一功能。
算法核心逻辑
翻转句子中单词顺序的标准算法思想包含两个关键步骤:
- 全局逆序:将输入字符串中的每个字符进行倒置,例如 "I am a student." 变为 ".tneduts a ma I"。
- 单词重置:遍历上一步得到的字符串,以空格为分隔符,识别出独立的单词并将其内部的字符再次逆序,恢复正确的单词拼写。
通过这种“先大后小”的转换,无需改变原始字符串的内存分配即可高效完成目标。
实现方案一:指针直接操作法
该方法使用两个指针从两端向中间移动来完成逆序操作,是底层逻辑最清晰的实现方式。
第1步:定义字符逆序函数
首先编写一个辅助函数 Reverse,接收指向起始位置和结束位置的指针。利用临时变量 temp 交换两端字符的值,并逐步向中心靠拢,直到指针交错。
void Reverse(char *pBegin, char *pEnd)
{
if(pBegin == NULL || pEnd == NULL)
return;
while(pBegin < pEnd)
{
char temp = *pBegin;
*pBegin = *pEnd;
*pEnd = temp;
pBegin ++, pEnd --;
}
}
第2步:实现句子翻转主函数
在 ReverseSentence 中,先用 pEnd 指针找到字符串末尾的 '\0',然后调用第一步的函数对整串进行逆序。接着重新初始化指针,遍历字符串:
- 当遇到非空格字符时,继续推进
pEnd定位单词边界。 - 一旦遇到空格或字符串结束符,说明找到了一个单词的范围,对该范围调用
Reverse。
char* ReverseSentence(char *pData)
{
if(pData == NULL)
return NULL;
char *pBegin = pData;
char *pEnd = pData;
// 1. 找到字符串末尾
while(*pEnd != '\0')
pEnd ++;
pEnd--;
// 2. 翻转整个句子
Reverse(pBegin, pEnd);
// 3. 翻转句子中的每个单词
pBegin = pEnd = pData;
while(*pBegin != '\0')
{
if(*pBegin == ' ')
{
pBegin ++;
pEnd ++;
}
else if(*rEnd == ' ' || *pEnd == '\0')
{
Reverse(pBegin, --pEnd);
pBegin = ++pEnd;
}
else
{
pEnd ++;
}
}
return pData;
}
第3步:测试验证
在 main 函数中定义测试用例,观察输出是否符合预期。
int main()
{
char input[] = "I am a student.";
printf("%s\n\n",input);
ReverseSentence(input);
printf("%s\n", input);
return 0;
}
实现方案二:数组下标迭代法
此版本采用经典的数组索引 low 和 high 来模拟边界查找过程,逻辑同样严谨,适合习惯下标操作的读者参考。
第1步:寻找单词边界
外层循环控制是否遍历完整个字符串长度 len。内层逻辑首先跳过前导空格(str[low] == ' '),然后将 low 赋值给 high 作为单词起点。
第2步:执行分段逆序
在确定单词区间后,通过 while(low < high) 循环交换首尾字符。值得注意的是,该实现最后使用了 printf 倒序输出的方式来直接打印结果,而非修改原数组。
#include <stdio.h>
#include <string.h>
int main()
{
char str[50001], ch;
int i, low, high, tmp, len;
while( gets( str ) )
{
len = strlen( str );
for( i = len - 1; i > 0; i-- )
printf("%c", str[i]);
printf("%c\n", str[0]);
}
return 0;
}
实现方案三:模块化函数重构
第三种方法将逆序逻辑抽离到 reverse_part 函数中,并在主流程中使用更简洁的条件判断来控制 pBegin 和 pEnd 的移动,代码可读性较强。
第1步:构建局部逆序函数
通过参数传递起始和结束索引,利用公式 i=(pEnd-pBegin)/2 计算遍历次数,高效完成指定区间的翻转。
void reverse_part(char *str,int pBegin,int pEnd)
{
char temp;
for(int i=pBegin;i<=(pEnd-pBegin)/2;++i){
temp=str[i];
str[i]=str[pEnd-i];
str[pEnd-i]=temp;
}
}
第2步:组合调用流程
主函数 reverse 先对整个字符串应用一次逆序,随后在一个 while 循环中检测空格位置。遇到空格时,立即触发上一阶段的 reverse_part 函数并更新起始点索引。
#include <iostream>
using namespace std;
void reverse_part(char*,int pBegin,int pEnd);
void reverse(char *str)
{
int n=strlen(str)-1;
reverse_part(str,0,n);
int pBegin=0,pEnd=0;
while(str[pEnd+1]){
if(str[pEnd]!=' ' && str[pEnd]!='\0')
++pEnd;
else{
reverse_part(str,pBegin,pEnd-1);
while(str[pEnd+1]!='\0' && str[pEnd+1]==' ')
++pEnd;
pBegin=++pEnd;
}
}
cout<<str<<endl;
}
总结
上述三种方案虽然具体的语法结构和变量命名有所不同,但核心均遵循了“全字翻转 + 单字重置”的逻辑闭环。在实际面试或工程应用中,需注意处理多个连续空格以及空字符串等边界情况以确保代码的鲁棒性。
以上就是C++实现翻转单词顺序的详细内容,更多关于C++字符串处理的资料请关注本站其它相关文章!
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













