1、反转单词。任意输入一串单词,要求把每个单词反转,但每个单词的位置不要改变。如输入:I am happy, 则输出:I ma yppah。
2、反转句子。任意输入一串单词,要求把每个单词的位置翻转过来,但每个单词的字母顺序不要改变。如输入:I am happy, 则输出:happy am I。
完整代码:
#include <iostream>
#include <string.h>
void reverse(char *B)
{
unsigned i;
int j = -1, k;
for (i = 0; i <= strlen(B); ++i)
{
if (B[i] && B[i] != ' ')
continue;
for ( k = i - 1; k != j; --k)
{
std::cout << B[k];
}
std::cout << " ";
j = i;
}
}
//问题一:
int main()
{
char a[100];
std::cin >> a;
reverse(a);
return 0;
}
//问题二:
int main()
{
char a[100];
std::cin >> a;
reverse(strrev(a));
return 0;
}
问题分析:
1、题目要求反转单词,只反转句子中的每个单词,单词的顺序并不改变;
2、首先需要把单词分离出来;
3、怎样算一个单词?第一个与第一个空格之间或者空格与下一个空格之间的x个字母可看为一个单词;
这部分可以这样计数:当当前的数组元素不为空,而且不是空格,就给x加1然后去判断下一个;
if(B[i] && B[i] != ' ') ++code;
4、将其中的这些字母(一个单词)反向输出;
for (int k(code-1); k != 单词开始的标记; - -k)
printf ( "%c", B[k]);
这样算一个单词反转完毕,需要加上空格在之后:
printf (" ");
5、单词开始的标记我们可以int j给它初始化为-1,因为如果当我们第一个单词只有一个字母时k = code-1 = 0,需要和B[j]进行比较,确保输出整个单词;这里code-1的原因是我们在技术时使用的++code,而数组的下标从零开始,所以此时的code表示的是最后一个字母之后的空格元素的下标;
6、每一次反转完成之后都需要移动单词开始的标记,让 其向后移动到目前单词结束的空格处,以便下一次控制长度;
所以需要在函数循环底部加上j = code;
所以我们的函数就可以写成:
void reverse(char *s)
{
int code, j = -1, k;
for (code = 0; code <= strlen(s); ++code)
{
if (s[code] && s[code] != ' ') continue;
for (k = code - 1; k != j; --k)
std::cout << s[k];
std::cout << " ";
j = code;
}
}
7、至于问题二:
要求我们只反转单词顺序,有了之前的基础,我们可以直接用一个strrev的库函数先反转整个句子让 i am happy 变成 yppah ma i然后在对我们反转后的新句子使用我们刚才的函数就会变成happy am i就可以顺利解决;
备注:完整代码里面i,k之所以定义成unsigned是因为strlen(char *s)返回的是无符号整型,当我们把一个无符号整型的数字和整型数字进行比较赋值的时候系统会警告,为了让其不出现警告,所以我们将控制下标的变量也定义成无符号整型;