【例10-9】编写一个函数reverse(char *s),实现将字符串s的内容就地逆置。要求用递归方法实现。
【分析】
在例题10-4中介绍了reverse()的非递归解法
【例10-4】编写一个函数reverse(char *s),实现将字符串s的内容逆置。例如,原字符串的内容为abcd,逆置后变为dcba。要求不另外开辟字符串空间。
【分析】
首先要将字符串保存在一个字符数组中,并将它的首地址作为函数reverse()c参数传递。在函数reverse()中,要实现将字符串内容的就地逆置(不另外开辟字符串空间),可以设置两个指针,分别指向字符串的首尾。然后将这两指针指向的位置互换,再将靠近字符串首的指针后移,靠近字符串尾的指针前移。重复上述操作,直到指针重合或者尾指针大于前指针(指针过界)为止。
下面给出完整的测试程序,程序清单10-4
#include "stdio.h"
void reverse(char *s)
{
int len = strlen(s)-1,i=0;
char tmp;
while(i!=len && i<len)
{
tmp = s[i];
s[i] = s[len];
s[len] = tmp;
i++;
len--;
}
}
main()
{
char s[]="abcdefgh";
printf("The string is %s\n",s);
reverse(s);
printf("The reversed string is %s\n",s);
getche();
}
。
但这里要求使用递归方法实现。可以仿照上一例题的做法,设len=strlen(s)-1,i=0。首先进行s[i]和s[len]的内容的置换,然后i自增1,len自减1.重复上述操作,这个过程用递归方法来实现,知道i的值等于len的值(当字符串中字符的个数为奇数),或者i的值大于len的值(当字符串中字符的个数为偶数)为止。算法描述如下:
void reverser(char *s,int len,int i)
{
char tmp;
if(i<len)
{
tmp = s[len];
s[len] = s[i];
s[i] = tmp;
reverser(s,len-1,i+1);
}
}
void reverse(char *s)
{
int len = strlen(s);
len--;
reverser(s,len,0);
}
函数reverse()是一个启动函数,它调用真正的递归函数reverser(),这样符合题目的要求,同时与例题10-4中的reverse()过程接口一致,易于软件的移植。在递归函数reverser()中,当i小于len时,就将s[len]的内容与s[i]的内容交换位置,然后递归地调用reverser()函数,此时参数len减1,参数i加1,。这个递归过程直到i>=len时结束。
下面给出完整的测试程序,程序清单10-9
#include "stdio.h"
void reverser(char *s,int len,int i)
{
char tmp;
if(i<len)
{
tmp = s[len];
s[len] = s[i];
s[i] = tmp;
reverser(s,len-1,i+1);
}
}
void reverse(char *s)
{
int len = strlen(s);
len--;
reverser(s,len,0);
}
main()
{
char s[]="abcdefg";
printf("The original string is %s\n",s);
reverse(s);
printf("The reversed string is %s\n",s);
getche();
}
本程序的运行结果如图所示