要求:
将一句话的单词进行倒置,标点不倒置。比如 "I like beijing.",经过处理后变为:"beijing. like I"。
字符串长度不超过100。
这里提供两种解题思路。
第一种:
先对整个字符串进行 逆序 操作 , 例如: I like beijing.
逆序后: .gnijieb ekil i
再对每个反过来的单词进行单独逆序,就能得到最后的答案 beijing. like I
首先建立逆序函数框架:传进来的 start 为我们所想输入的数组的 首地址 ,end则为最后一个结束的元素的地址。
void daozhi(char*start, char*end) { char tem = 0; while (start<end) { tem = *start; *start = *end; *end = tem; start++; end--; } }
建立中体架构,嵌入函数
int main() { char arr[100]; gets(arr); char*start = arr; int len = strlen(arr); char*end = arr + len - 1; daozhi(start, end); printf("%s\n", arr); return 0; }
在这里没有使用 scanf ( "%s", arr )是因为读取结束的时候scanf会把最后的回车也存入缓存区,在后面进行单个单词的逆序的时候会产生换行错位。( 这里可以将原来的scanf函数改为
:scanf("%[\^n]",arr);并在scanf后面加上getchar()来移除这个回车,也可以使用fflush(stdin)。)
单个字母的逆序:
这里我们知道,和只要知道一个字符串的首地址,尾地址就可以将整个字符串逆序,那么对于单词来讲,那我们只需要知道单词的第一个字母对应的地址,和最后一个字母对应的地址,我们就可以利用之前的逆序函数进行局部逆序。
.gnijieb ekil i 就拿这个例子来说,可以看出每个单词之间都是用‘ ’(空格)来间隔的,除了最后面的 i 后面是‘\0’,在判断是否是 空格 或者 \0 的时候可以利用 || 逻辑运算符。
空格 和 \0 的读取可以想到用arr[ i ]==' ' || arr[ i ] ==' \0 '。因为要读取到 \0 ,所以用for循环来寻找空格或者 \0的时候,循环的次数就变为了len+1。
char*s = arr; for (int i = 0; i <=len; i++) { if (arr[i] == ' ' || arr[i] == '\0') { daozhi(s,arr+i-1); s = arr + i + 1; } }
最后打印 printf("%s\n",arr);
完整的代码:
#include<stdio.h> #include<string.h> void daozhi(char*start, char*end) { char tem = 0; while (start<end) { tem = *start; *start = *end; *end = tem; start++; end--; } } int main() { char arr[100]; scanf("%[\^n]s", arr); getchar(); char*start = arr; int len = strlen(arr); char*end = arr + len - 1; daozhi(start, end); char*s = arr; for (int i = 0; i <=len; i++) { if (arr[i] == ' ' || arr[i] == '\0') { daozhi(s,arr+i-1); s = arr + i + 1; } } printf("%s\n", arr); return 0; }
第二种:
先对单个单词进行逆序,再对整个句子进行逆序;
例如 i like beijing.
单个逆序后 i ekil .gnijieb
再整体逆序 beijing. like i
完成打印 printf("%s\n",arr);
(字符串逆序上面已经提出这里不在赘述)
void reverse(char* left, char* right) { while (left < right) { char t = *left; *left = *right; *right = t; left++; right--; } }
首先是对单个单词的逆序(这里直接使用自定义的reverse()逆序函数)
int main() { char arr[100]; gets(arr); char* tem = arr; char* start = tem; char* end = tem; while (1) { while (*end != ' '&&*end != '\0') { end++; } reverse(start, end-1); start = end + 1; if (*end == ' ') end++; else if (*end == '\0') break; }
单个单词的判断标准仍然是 空格 和 \0 。
进入while(1)循环后,寻找每个单词 首字母 和 尾字母 的指针并将其输入到自定义的reverse()函数里面去逆序,然后找下一个单词。
在判断为end==‘\0’之时跳出循环
当所有的单词都逆序之后,然后对整体逆序,将这个句子的首字母的指针和尾字符.的指针输入到reverse()函数里面去完成逆序,并打印。
int len = strlen(arr); char* right = arr + len - 1; reverse(arr, right); printf("%s", arr);
完整代码:
#include<stdio.h> #include<string.h> void reverse(char* left, char* right) { while (left < right) { char t = *left; *left = *right; *right = t; left++; right--; } } int main() { char arr[100]; gets(arr); char* tem = arr; char* start = tem; char* end = tem; while (1) { while (*end != ' '&&*end != '\0') { end++; } reverse(start, end-1); start = end + 1; if (*end == ' ') end++; else if (*end == '\0') break; } int len = strlen(arr); char* right = arr + len - 1; reverse(arr, right); printf("%s", arr); return 0; }