要求:
将一句话的单词进行倒置,标点不倒置。比如 "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;
}