关于递归实现字符串反转,没想到字符随机写入操作,不new就不行?

c++题目:

用递归思想实现字符串反转。

原型给出: char *reverse(char *str){}

初一看,嘿嘿,感觉蛮简单的,递归嘛,不就是子问题处理的原理跟大问题处理的原理一致,然后根据递推,直到找到

自问题的设定条件,接着反推回去,找到大问题的答案,这是我个人的理解。

比如:

有七个人,求老大的岁数,条件,老大比老二大2岁,老二比老三大2岁。。。。。老七的岁数是70,请问老大的岁数?

类似这道题很经典。思路:设定老大岁数N1, 老二为N2。。。。老七N7,根据条件,得到:

N1 = N2 + 2

N2 = N3 +2

...............

N7 = 70;

具体算法:

int f(int n)

{

   if(n == 7)

       return 70;

   int  m =  f(n - 1) + 2;

   return m;

}

求老大到岁数调用f(1);

好了,那么对于面试题的递归呢?具体如下:

char *reverse(char *str)

{

   if ('\0'==  str[0]) {

        

        return nullptr;

    }

    

   size_t len =strlen(str);

    

   if (len >1) {

       char ch = str[0];

        str[0] = str[len -1];

        str[len -1] ='\0';

       reverse(str +1);

        str[len -1] =  ch;

    }

    

   return str;

}

int main()

{   

    char *res =reverse("abcdefg");

   cout << res <<endl;

   return 0;

}


看起来一切都好,嗯,在xcode上的调试下,呀,出现了以下的东西啊。如图:

神马意思啊,英文不好,出现了EXC_BAD_ACCESS,一般来说,这是使用了没有分配内存空间的指针而导致的,那是不是,str[]的问题呢?我们看下

能不能读出来:

char *printStr(char *str)

{

   size_t len =strlen(str);

   for (int i =0; i < len; ++i) {

       cout << str[i] <<" ";

    }

   cout <<"\n";

   return  str;

}

然后在main中调用

    char *res =printStr("abcdefg");

a b c d e f g 

Program ended with exit code: 0

输出正确,那说明读取是没有问题的。

那我们看下这是不是使用了没有分配内存空间的指针而导致的,因为这里是对字符串对写入操作str[0] = str[len -1], 而这里分配的内存空间呢,没有。好,我换下输入,在main函数改为:

   char *p =newchar(20);

   sprintf(p,"abcdefg");

   char *res =reverse(p);

   cout << res <<endl;

这下好了结果如下:

gfedcba

Program ended with exit code: 0

不过在最后需要释放掉new 出来的内存:

    delete p;


所以原因就是没有分配内存,而执行写入操作导致程序崩溃。
关于这个字符串递归算法就到这了,以下是非递归的实现,供大家参考:


char *reverse_f(char *str)

{

   size_t len =strlen(str);

   int i =0;

   while (i < len /2) {

       char ch = str[i];

        str[i] = str[len -1 - i];

        str[len -1 - i] = ch;

        ++i;

    }

   return str;

}


而下面这中图得比较方便,坏点就是使用了new,很容易造成内存泄漏,使用者必须小心谨慎。

char * reverse_s(char *str)

{

   size_t len =strlen(str);

   char *p =newchar(len +1);

   int i =0;

   while (i < len) {

        p[i++] = str[len - i -1];

    }

    p[i] ='\0';

   return p;

}




汉诺塔递归调用:


void move(int num,char b, char c)

{

   cout << "number:" <<  num <<" from " << b << " to " << c <<endl;

}


void hanTowar(int n,char a, char b,char c)

{

   if (n == 1) {

       move(1, a, c);

       return;

    }

   else

    {

       hanTowar(n - 1, a, c, b);

       move(n, a, c);

       hanTowar(n-1, b, a, c);

    }

    

}

int main()

{

    

   hanTowar(3,'a', 'b', 'c');

    return 0;

}



欣赏下下面点递归:



void out(int n)

{

    if (!n)   return;

    cout << "*";

    out(n-1);

  

}

void start(int n)

{

    if(!n) return;

    out(n);

    cout << "\n";

    start(n-1);

    out(n);

      cout << "\n";

}

int main()

{

    

    start(7);

}




void out(int n)

{

    if (!n)   return;

    cout << "*";

    out(n-1);

  

}

void start(int n)

{

    if(!n) return;

    out(8 - n);

    cout << "\n";

    start(n-1);

    out(8 - n);

      cout << "\n";

}

int main()

{    

    start(7);

}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值