单词倒排,链接奉上。
方法
- 做题前的预备知识
- 双指针
- 逆序整个+逆序单词
做题前的预备知识
在做题时遇到有关判断字母与数字时,因为总会写成
str>'0'&&str<'9'
之类的形式,比较繁琐,而C语言为了解决这个问题,有了以下库函数
详情可看:
cplusplus链接
博客链接
双指针
思路:
1.定义快慢指针
p1,p2
2.从后往前遍历,p1指向'\0'
的前一个
3.p1
要指向单词的末尾,当p1
指向的不是末尾时,p1--
,直到p1
指向末尾,用p2
记录
4.继续寻找单词的开头,因此当s[p1]
为字母的时候就让p1--
,最终p1+1
指向该单词的开头
5.我们从p1+1
遍历到p2
,依次打印即可。
代码实现:
#include<stdio.h>
#include<ctype.h>
#include<string.h>
int main()
{
char s[10000];
gets(s);
//用gets接收不会因为遇到空格停止,sacnf会因为空格停止
int len = strlen(s);
int p1 = len - 1, p2 = len;
while(p1 >= 0)
{
while(p1 >= 0 && !isalpha(s[p1]))
p1--;
p2 = p1;
while(p1 >= 0 && isalpha(s[p1]))
p1--;
for(int i = p1 + 1; i <= p2; i++)
printf("%c", s[i]);
printf(" ");
}
return 0;
}
逆序整个+逆序单词
整体思路:
1.先将整个字符串逆序
2.再将字符串中的单词逆序
3.最后打印字符串
-
思路实现:
-
逆序思路:
1.将逆序设计为一个函数,需要时就使用
2.逆序时要传入首元素(start
)与尾元素(end
)地址
3.定义一个临时变量用来交换首尾元素,将此过程放入while
中,控制循环的变量为start<end
-
将整个字符串逆序:
利用strlen
找到尾元素地址,传入逆序函数 -
将每个单词逆序:
遍历字符串,找到每个单词的开头与结尾,传入逆序函数 -
打印:
注意非字母元素不能打印,并且单词之间只能打印一个空格
代码实现:
#include <stdio.h>
#include<string.h>
void reverse(char* start, char* end)//逆序函数
{
while (start < end)
{
char tmp = *start;
*start = *end;
*end = tmp;
start++;
end--;
}
}
int main()
{
char str[10000];
gets(str);
char* tmp = str;
int len = strlen(str);
reverse(str, str + (len - 1));
char* start = tmp;
char* end;
while (*tmp)
{
if (isalpha(*tmp))
//当*tmp为字母时,tmp++,找到非字母元素
{
tmp++;
if (*tmp == 0)
//当*tmp==0时,说明已经到了末尾,会跳出循环,所以要在循环内时进行判断
{
end = tmp - 1;
reverse(start, end);
}
}
else
//进入else说明*tmp是非字母元素
{
end = tmp - 1;
reverse(start, end);
while (*tmp != 0 && !isalpha(*tmp))
//跳过非字母元素,并将非字母元素赋值为空格,为了打印时好操作
{
*tmp = ' ';
tmp++;
}
if(*tmp != 0)
start = tmp;
}
}
for (int i = 0; i < len; i++)//打印
{
if (str[i] != ' ')
printf("%c", str[i]);
else
{
while (str[i] == ' ' && str[i] != 0 && str[i + 1] == ' ')
{
i++;
}
printf(" ");
}
}
return 0;
}
第二个方法代码,大家如果有优化的方案的话,请尽情留言。