以单词为最小单位翻转字符串
Sailor_forever sailing_9806@163.com 转载请注明
http://blog.csdn.net/sailor_8318/archive/2007/09/10/1778566.aspx
××××××××××××××××××××××××××××
write the function string reversestringwordbyword(string input) that reverses a string word by word. for instance,
reversestringwordbyword('the house is blue') --> 'blue is house the'
reversestringwordbyword('zed is dead') --> 'dead is zed'
reversestringwordbyword('all-in-one') --> 'all-in-one'
××××××××××××××××××××××××××××
算法一 递归方式,递归寻找最后一个单词,将其拷贝到des,返回拷贝后的des指针,供上层调用继续拷贝其前面的单词,依次类推,最后拷贝完整个字符串
char *reverse_str_word_by_word(char *des, char *src)
{
char *p1 = src;
int length;
if ((NULL == des) || (NULL == src))
return NULL;
while (*p1)
{
//length = p1-src; // error for the last word
if (' ' == *p1)
{
// the new src is p1+1 except ' '
des = reverse_str_word_by_word(des,p1+1);
// overwrite the previous '/0' by ' ' to save another word
*des++ = ' ';
memcpy(des, src, length);
*(des+length) = '/0'; // in case it is the end
return des+length;
}
p1++;
length = p1-src;
}
//this is the last word or only one word
memcpy(des, src, length);
*(des+length) = '/0'; // in case it is the end
// return the initial revised dest addr
return des+length;
}
××××××××××××××××××××××××××××
算法二 递归方式改进版,去掉了数组长度变量, 将最后一个单词和中间递归调用的拷贝单词整合到了一块,代码更简洁,但是第一种的递归退出和再调用条件更明确
char *reverse_str_word_by_word(char *des, char *src)
{
char *p1 = src;
if ((NULL == des) || (NULL == src))
return NULL;
while (*p1)
{
if (' ' == *p1)
{
des = reverse_str_word_by_word(des,p1+1);
// overwrite the previous '/0' by ' ' to save another word
*des++ = ' ';
break;
}
p1++;
}
//this is the last word or for breaking
memcpy(des, src, p1-src);
des += p1-src;
*des = '/0'; // in case it is the end
// return the revised dest addr
return des;
}
int main()
{
char src1[] = "zed is dead";
char src2[] = "all-in-one";
char src3[] = "the house is blue";
char dst[30];
reverse_str_word_by_word(dst,src1);
printf("reverse_str_word_by_word of /"zed is dead/" is %s/n", dst);
reverse_str_word_by_word(dst,src2);
printf("reverse_str_word_by_word of /"all-in-one/" is %s/n", dst);
reverse_str_word_by_word(dst,src3);
printf("reverse_str_word_by_word of /"the house is blue/" is %s/n", dst);
system("pause");
return 0;
//reverse_str_word_by_word of "zed is dead" is dead is zed
//reverse_str_word_by_word of "all-in-one" is all-in-one
//reverse_str_word_by_word of "the house is blue" is blue is house the
}
××××××××××××××××××××××××××××
算法三 传统算法,从后往前,依次拷贝,
/*
* name: reverse_src_word_by_word
* params:
* des [out] 输出字符串, des 指向实现申请的空间
* src [in] 输入字符串,需要处理的字符串
* return:
* 处理完成后的 des 指针
* notes:
* 以单词为最下单位翻转字符串
* author: a.tng 2006/06/16 9:06
*/
char *reverse_str_word_by_word(char *des, char *src)
{
char *p1, *p2;
char *psz_dest;
if ((null == des) || (null == src))
return null;
/* 从 src 的最后一个字符开始遍历 */
p1 = src + strlen(src) - 1;
p2 = p1;
psz_dest = des;
while (p1 != src)
{
if (' ' == *p1)
{
int n_len;
/* 找到一个单词,拷贝单词 */
n_len = p2 - p1;
memcpy(psz_dest, p1 + 1, n_len);
psz_dest += n_len;
*psz_dest++ = ' ';
/* 准备寻找下一个单词 */
p1--; p2 = p1;
}
else
{
/* p1 往前移一位 */
p1--;
}
}
/* 最后一次拷贝单词 */
if (p1 != p2)
{
int n_len;
n_len = p2 - p1 + 1;
memcpy(psz_dest, p1, n_len);
psz_dest += n_len;
*psz_dest = '/0';
}
return des;
}
比较费空间,因为多申请了一段空间来保存结果。
××××××××××××××××××××××××××××
算法四 整体翻转,每个单词局部翻转,多次利用字符串翻转
在看了其他高手的实现后,发现可以不用申请空间,并且循环的次数更少,也可以实现相同的效果。
原字符串: the house is blue
先翻转整个字符串-> eulb si esuoh eht
再翻转单个单词
#define reverse_word(p1, p2) while (p1 <= p2) /
{ /
char ch; /
ch = *p1; *p1 = *p2; *p2 = ch; /
p1++; p2--; /
}
/*
* name: reverse_src_word_by_word
* 优化: 先翻转整个字符串,再翻转单个单词
* * author: a.tng 2006/06/16 10:37
*/
char * reverse_str_word_by_word2(char *src)
{
char *p1, *p2;
int n_src_len;
if (null == src)
return null;
/* 先把整个字符串翻转一次 */
n_src_len = strlen(src);
p1 = src; p2 = src + n_src_len - 1;
reverse_word(p1, p2);
#if 0
while (p1 <= p2)
{
/* 交换头字符和尾字符 */
char ch;
ch = *p1; *p1 = *p2; *p2 = ch;
p1++; p2--;
}
#endif
/* 再翻转单个单词 */
p1 = src; p2 = p1;
while ('/0' != *p2)
{
if (' ' == *p2)
{
char *p;
p = p2 - 1;
reverse_word(p1, p);
#if 0
while (p1 <= p)
{
char ch;
ch = *p1; *p1 = *p; *p = ch;
p1++; p--;
}
#endif
p2++;
p1 = p2;
}
else
{
p2++;
}
}
/* 翻转最后一个单词 */
p2--;
reverse_word(p1, p2);
#if 0
while (p1 <= p2)
{
char ch;
ch = *p1; *p1 = *p2; *p2 = ch;
p1++; p2--;
}
#endif
return src;
}
int main()
{
// char src[] = ' all-in-one ';
// char src[] = 'the house is blue';
char src[] = 'zed is dead';
(void) reverse_str_word_by_word2(src);
printf('*****%s*****/n', src);
system('pause');
}
参考资料: