问题引入
将一句话的单词进行倒置,标点不倒置。比如 I like beijing. 经过函数后变为:beijing. like I
输入描述
:
每个测试输入包含1个测试用例: I like beijing. 输入用例长度不超过100
输出描述
:
依次输出倒置之后的字符串,以空格分割: beijing. like I
一、思路
- 可以先将整句逆序,再将每个单词逆序;也可以先将每个单词逆序,再将整句逆序。
- 自定义逆序函数reverse(),无返回值;其参数列表放入需要逆序的单词或句子的首尾地址(char* left, char* right);函数体采用循环,不断交换首尾地址的对象,每交换一次,分别将首地址+1,尾地址-1,直到首地址大于尾地址不满足交换条件时,交换结束。
- 找每个单词的首尾地址:先将首尾地址都设为数组首地址arr,接下来遍历尾地址end,直到尾地址为空格时,表示第一个单词结束,则尾地址就是空格前一个,即end-1;此时,首地址更新为空格后一个,即end+1;以此循环,直到遍历到‘\0’(字符串结束标志)即句末时结束循环。按此方法,即可得到每一个单词的首尾地址。
- 找整个句子的首尾地址:首地址即数组首地址arr,尾地址则用首地址加上数组的长度再减去一即可。
二、代码展示
代码如下:
#include <stdio.h>
#include<string.h>
#include<assert.h>
void reverse(char* left, char* right) {
assert(left);
assert(right);
while (left < right) {
char temp = *left;
*left = *right;
*right = temp;//交换首位地址的对象
left++;
right--;
}
}
int main() {
char arr[101] = { 0 };
gets(arr);
char* cur = arr;//定义指针变量cur存储arr首地址
while (*cur) {//cur='\0'结束循环
char* start = cur;//定义start指针变量
char* end = cur;//定义end指针变量
while (*end != ' ' && *end != '\0') {//end遍历直到空格或句末停止
end++;
}
//对每个单词进行逆序
reverse(start, end - 1);
if (*end !='\0') {
cur = end + 1;//首地址cur更新
}
else {
cur = end;//cur='\0'
}
}
int len = strlen(arr);//计算数组长度
//对整个句子进行逆序
reverse(arr, arr + len - 1);
//输出
printf("%s\n", arr);
return 0;
}
投机方法
- 该方法采用递归,每读一个字符串先放入arr中不打印,等递归往回的时候再倒着打印。
- 弊端:该方法只是通过读的方式对字符串进行了逆序输出,本质上并没有将该字符串存起来进行倒置。
代码如下:
#include<stdio.h>
void reverse() {
char *arr[101];
if (scanf("%s",arr)!= EOF) {
reverse();
printf("%s ", arr);
}
}
int main() {
reverse();
return 0;
}
提示:一般建议使用第一种方法,第二种方法仅了解,避免在其他情况中使用出现错误!还有其他思路和方法的也可以一起交流,有错误的地方欢迎指正。