闲来无事刷leetcode,随便挑了一道翻转字符串的题,其实这道题之前在九度上做过,剑指offer里也有讲,但是我还是花了很久才AC。这次是用纯C写的,觉得用纯C处理字符串才锻炼真本事。
遇到这样的题,要习惯性地问几个问题:
1.字符串前后是否空格,有的话怎么处理,删除还是跟着一起旋转或者保持不变
2.单词之间的空格是否只有一个,如果不是,应该只保留一个还是跟着一起旋转
3.空格之外的字符是不是只有英文字母,如果不是,怎么样算一个单词
leetcode上的设定是:
1.前后可能有空格,有则直接删除,所以我就谢了预处理代码
2.单词间空格不一定只有一个,结果只保留一个,所以我写了deSpace函数
3.只要连在一起就算一个单词,所以不需有过多考虑
因此我的代码如下:
//该函数实现整个字符串翻转
void reverseWord(char* s, int front, int back)
{
if (s == NULL)
return;
int i = front, j = back;
char temp;
while (i < j)
{
temp = s[i];
s[i] = s[j];
s[j] = temp;
++i;
--j;
}
}
//实现去除单词之间的多余空格
int deSpace(char*s, int len)
{
int cnt = 0, pos = -1, i = 0;//pos记录下一个字符应该出现的位置
for (i = 0; i < len; ++i)
{
if (s[i] != ' ')
{
++pos;
cnt = 0;//不是空格则取消之前的空格计数
}
else
{
++cnt;//遇到空格则进行计数
if (cnt == 1)
{
++pos;
}
}
if (pos < i)//如果当前位置与应该出现的位置不符,则进行移动
{
s[pos] = s[i];
}
}
s[pos + 1] = '\0';
return strlen(s);
}
void reverseWords(char *s) {
if (s == NULL)
return;
int len = strlen(s);
int start = 0, k;
//删除字符串开头的空格
while (s[start] == ' ' && start < len)
++start;
if (start >= len)
{
s[0] = '\0';
return;
}
else
{
k = 0;
for (k = start; k <= len; ++k)
{
s[k - start] = s[k];
}
}
//删除字符串结尾的空格
len = strlen(s);
int end = len - 1;
while (s[end] == ' ')
--end;
s[end + 1] = '\0';
len = strlen(s);
//删除多余空格并翻转整个字符串
len = deSpace(s, len);
reverseWord(s, 0, len - 1);
//对单词进行逐个翻转
int i, j;
int front = 0, back = 0;
for (i = 0; i < len; ++i)
{
if (s[i] != ' ')
{
back = i;
}
else
{
reverseWord(s, front, back);
if (i + 1 < len)
{
front = i + 1;
back = i + 1;
}
}
}
reverseWord(s, front, back);
}