1.题目描述
2.解题步骤
首先我们要完成这道题
1.翻转字符串中所有的单词
2.删除多余的空格
①翻转字符串中所有的单词
这个步骤中有个技巧:我们先①把整个字符串翻转,②所有单词的字母翻转,就能得到翻转单词后的字符串,①步骤和②步骤谁先谁后都可以,例如:
gif
所以这个步骤应该就不难实现啦,只需要循环和双指针,一个记录起始位置,一个记录空格位置,就能实现所有单词内部字母翻转,循环结束后再整个翻转!
实现代码
void reverse(char* begin, char* end) //翻转函数
{
while (begin <= end)
{
char temp = *begin;
*begin = *end;
*end = temp;
end--;
begin++;
}
}
char* reverseWords(char* s)
{
int i = 0, j = 0;
int len = strlen(s);
while (i < len)
{
//找出单词中第一个字母和最后一个字母的小标
while (j < len && isspace(s[j])) //找到第一个字母的下标
{
j++;
}
i = j; //更新i的指向
while (j < len && !(isspace(s[j]))) //找到最后一个字母的下标
{
j++;
}
reverse(s + i, s + j - 1);
i = j; //更新i的指向
}
reverse(s, s + len - 1);
RemoveSpace(s, len); //移除多余的空格,这一步下面会讲解
return s;
}
②删除多余的空格
题目指出空格可能会连续出现多次,或者出现在字符串的开头,还有出现在字符串的结尾。
那么我们的目的就是,把字符串一开头就出现的空格,单词间多余的空格,和最后出现的空格都给清除掉
1.为了清除掉出现在字符串最前面的空格,我们可以直接让快指针fast跳过前面的空格,也就是这样
while (isspace(s[j]))
{
j++;
}
2.为了清除单词间多余的空格,并不是清除掉单词间的全部空格,而是还要保留一个空格作为分隔,所以我们的双指针在覆盖时,需要把 单词间第一个空格一起覆盖过去,代码如下。
//处理中间部分
while (j < len)
{ //如果前面那个字符也是空格,也就是我们不需要覆盖的字符,直接跳过就行
if (j > 0 && isspace(s[j - 1]) && isspace(s[j]))
{
j++;
}
else //覆盖,覆盖完两个都要++
{
s[i++] = s[j++];
}
}
3.而最后的尾巴,只有两种情况,第一:覆盖完后没有空格。第二:覆盖完后只有一个空格,我们对应不同的情况,在结尾加上\0即可。代码如下:
if (i > 0 && isspace(s[i - 1])) //如果覆盖完后的最后一个字符是空格
{
s[i - 1] = '\0';
}
else //如果覆盖完后不是空格
{
s[i] = 0;
}
gif
实现代码
void RemoveSpace(char* s, int len)
{
int i = 0;
int j = 0;
//防止一开始就是空格
while (isspace(s[j]))
{
j++;
}
//处理中间阶段
while (j < len)
{
if (j > 0 && isspace(s[j - 1]) && isspace(s[j]))
{
j++;
}
else
{
s[i++] = s[j++];
}
}
//处理收尾阶段
if (i > 0 && isspace(s[i - 1]))
{
s[i - 1] = '\0';
}
else
{
s[i] = 0;
}
}
3.完整代码
void RemoveSpace(char* s, int len)
{
int i = 0;
int j = 0;
//防止一开始就是空格
while (isspace(s[j]))
{
j++;
}
//处理中间阶段
while (j < len)
{
if (j > 0 && isspace(s[j - 1]) && isspace(s[j]))
{
j++;
}
else
{
s[i++] = s[j++];
}
}
//处理收尾阶段
if (i > 0 && isspace(s[i - 1]))
{
s[i - 1] = '\0';
}
else
{
s[i] = 0;
}
}
void reverse(char* begin, char* end)
{
while (begin <= end)
{
char temp = *begin;
*begin = *end;
*end = temp;
end--;
begin++;
}
}
char* reverseWords(char* s)
{
int i = 0, j = 0;
int len = strlen(s);
while (i < len)
{
//找出单词中第一个字母和最后一个字母的小标
while (j < len && isspace(s[j]))
{
j++;
}
i = j;
while (j < len && !(isspace(s[j])))
{
j++;
}
reverse(s + i, s + j - 1);
i = j;
}
reverse(s, s + len - 1);
RemoveSpace(s, len);
return s;
}