代码在5_23中
一、字符串逆序
首先,先实现字符串的逆序。(其实这里有两种情况,第一个是不更改原先字符串内容,在屏幕上逆序打印;第二个是将原先字符串内容逆序,再正着打印。这两种在屏幕上显示的内容是一样的,但具体是哪一种要看题目要求)
(一)不更改原先字符串内容,在屏幕上逆序打印
先看一下代码是如何如何实现的:
#include <stdio.h>
#include <string.h>
int main()
{
char arr[20] = { 0 };
gets(arr);
int len = strlen(arr);
char* end = arr + len - 1;
char* start = arr;
while (start <= end)
{
printf("%c", *end);
end--;
}
return 0;
}
这里的思路是:先用一个char* 指针找到字符串中的最后一个字符,然后向前移动并打印,直到该指针移动到第一个字符时,停止打印。
注:这里输入一个字符串用的是 gets 函数,没有用 scanf , 因为 scanf 输入的时候遇到空格就会停止,所以使用 gets .
(二)逆序原字符串
#include <stdio.h>
#include <string.h>
int main()
{
char arr[20] = { 0 };
gets(arr);
char* left = arr;
int len = (int)strlen(arr);
char* right = arr + len - 1;
while (left < right)
{
char temp = *left;
*left = *right;
*right = temp;
left++;
right--;
}
puts(arr);
return 0;
}
二、单词逆置
题目链接:倒置字符串__牛客网 (nowcoder.com)
题目描述:
将一句话的单词进行倒置,标点不倒置。比如 I like beijing. 经过函数后变为:beijing. like I
输入描述:
每个测试输入包含1个测试用例: I like beijing. 输入用例长度不超过100输出描述:
依次输出倒置之后的字符串,以空格分割输入
I like beijing.输出
beijing. like I
先看一下题解代码:
#include <stdio.h>
#include <string.h>
void reverse(char* left, char* right)
{
while (left < right)
{
char temp = *left;
*left = *right;
*right = temp;
left++;
right--;
}
}
int main()
{
char arr[101] = { 0 };
gets(arr);
//逆序整个字符串
int len = (int)strlen(arr);
reverse(arr, arr + len - 1);
//逆序每一个单词
char* start = arr;
char* end = start;
while (*start != '\0')//当*start等于\0时,停止逆序
{
while (*end != ' ' && *end != '\0')//注意最后一个单词的后面不是空格
{
end++;
}
reverse(start, end - 1);
if(end != '\0')//如果最后一个单词在向后移动时,会导致start跳过\0从而导致死循环
end++;
start = end;
}
puts(arr);
return 0;
}
题解思路:
根据题目描述,倒置字符串跟逆序字符串的思路非常相似,两者的区别在于:倒置字符串是在逆序字符串的基础上再将每一个单词进行逆序,这里逆序单词和逆序一个字符串可以用一个函数来实现(单词本身就是一个字符串)。
下面我们就需要先将整个字符串逆序,然后找到整个字符串中的每一个单词,再将每一个单词进行逆序即可。
这里先说一下,一个单词是如何逆序的:需要两个指针,一个头指针指向单词首字母,一个尾指针指向单词尾字母;第一次将单词的首尾字母交换,头指针向后移动,尾指针向前移动,交换第二对字母,之后是同样的步骤,知道所有字母对都交换完成。
void reverse(char* left, char* right)
{
while (left < right)
{
char temp = *left;
*left = *right;
*right = temp;
left++;
right--;
}
}
既然要找到每一个单词,那就需要遍历,而单词和单词之间都有一个空格,我们可以用一个字符指针进行遍历,遇到空格时就停一下,空格前的字符串就是一个单词。然后 end 向后移动,此时 end 指向下一个单词的首字母,在将 start 指向与 end 同一个位置的字母,然后再让 end 遍历知道再次遇到空格后停下来。当 start 指向 \0 时停止循环。
char* start = arr;
char* end = start;
while (*start != '\0')//当*start等于\0时,停止逆序
{
while (*end != ' ')
{
end++;
}
reverse(start, end - 1);
end++;
start = end;
}
但这里要注意,最后一个单词的后面没有空格而是 ‘\0’, 所以当 end 再遇到 '\0' 时也应该停下来,否者到逆序最后一个单词时,就会找不到单词的尾字母了。
所以代码就变成:
while (*start != '\0')//当*start等于\0时,停止逆序
{
while (*end != ' ' && *end != '\0')//注意最后一个单词的后面不是空格
{
end++;
}
reverse(start, end - 1);
end++;
start = end;
}
注意这里的 end 是指向空格的,所以要向指向下一个单词的首字母时,需要 end++.
但是这里还会有一个问题,当遇到最后一个单词时,end 遍历后指向 \0, 当 end++ 后,end 指向 \0 后面的位置,这也就意味着 start 也会指向 \0 后面的位置;还记得逆序字符串的停止条件吗?(*start != '\0'),start 不会指向 \0 循环也就不能够停止了,所以这里并不能让 end 指向 \0 时再向后移动,所以这里需要加一个条件。 代码变为:
while (*start != '\0')//当*start等于\0时,停止逆序
{
while (*end != ' ' && *end != '\0')//注意最后一个单词的后面不是空格
{
end++;
}
reverse(start, end - 1);
if(end != '\0')//如果最后一个单词在向后移动时,会导致start跳过\0从而导致死循环
end++;
start = end;
}
逆置字符串基本完成了。
这里还有一些小问题:当输入一个字符串时,你选择使用 fgets ,结果会变为
这里涉及 fgets 的使用细节 --换行符使 fgets 停止读取,但它被函数视为有效字符,并包含在复制到 str 的字符串中, 也就是说 \n 也被赋值进字符串中了,所以在打印的时候,Beijing. 后面会有一个换行的操作。
————————————————————————
今天的分享就到这里了,如果,你感觉这篇博客对你有帮助的话,就点个赞吧!感谢感谢……