字符串逆序输出与main函数的递归调用
来源:互联网 发布:二手淘宝网首页 编辑:程序博客网 时间:2024/05/22 13:50
昨天有人问问了我这样一道题,如何不利用第三方变量,将字符串逆序输出。我给出了几种方案,有非递归的,也有递归的。
一:
首先来非递归的,这个就比较简单了,直接利用strlen函数求得字符串长度,然后逆序输出即可。
代码如下:
#include <iostream>#include <string.h>void reverse_str(const char *str){auto len = strlen(str);for(int i=len-1; i>=0; --i){std::cout << str[i];}}int main(int argc, char ** argv){if(argc != 2){fprintf(stdout, "Usage %s <string>\n", argv[0]);exit(EXIT_FAILURE);}reverse_str(argv[1]);return 0;}
二:
其次为递归方法,递归的思路是函数压栈,当检测到\0,递归终止,然后函数出栈,逆序打印每个字符。
其中有两点值得注意:
1、字符串作为全局变量
<pre name="code" class="cpp">#include <iostream>const char *str = "iloveyou";void reverse_string(const char *){if(*str != '\0')reverse_string(++str);if(*str != '\0')std::cout << *str;--str;}int main(int argc, char** argv){reverse_string(str);return 0;}
这种递归方法显然可以成功,然后我又想用字符串定义在主函数,利用主函数调用的方式。
2.字符串作为主函数局部变量
(1)++str
我首先用了这样的写法:
//wrong#include <iostream>void reverse_string(const char *str) //error,因为++str如果在底层函数中改变,想要在上一层保留变动结果,需要传递引用。{if(*str != '\0')reverse_string(++str); //if(*str != '\0')std::cout << *str;--str;}int main(int argc, char** argv){const char *str = "iloveyou";reverse_string(str);return 0;}
这个写法困扰了我好长时间,它总是打印不到第一个字母,后来我突然意识到,如果需要在递归子程序里面改变参数的值,就需要传递引用给它,这样才能保留你要做的改动,并返回给上一层。下面这种写法才是正确的:
#include <iostream>void reverse_string(const char *&str) //right,传递引用{if(*str != '\0')reverse_string(++str); if(*str != '\0')std::cout << *str;--str;}int main(int argc, char** argv){const char *str = "iloveyou";reverse_string(str);return 0;}(2)str+1
另外一种写法就是直接用str+1,这样你的str指针始终指向不变,只是传递给下一层的参数,是你的str+偏移量的那个地址,相当于tmp = str +偏移量,tmp传给下一层子函数。而不是str++, str++其实是 str = str + 1,str自身指向也改变了。
由于每一层子函数都有自己的str+偏移量结果,自然不需要传递引用了,因为我们不需要也不会改变str的指向,也就不需要--str了。代码如下:
#include <iostream>void reverse_string(const char *str) //由于不用改变str,所以不需要传递引用{if(*str != '\0')reverse_string(str+1); //对应str+1if(*str != '\0')std::cout << *str;//--str; //每一层都有自己的str+偏移量}int main(int argc, char** argv){const char *str = "iloveyou";reverse_string(str);return 0;}
三:
终极方法:main函数的递归调用实现字符串逆序输出。
1.首先我给出了这样的写法:
#include <iostream>char* str = "iloveyou";int main(char *, char **argv = NULL){if(*str != '\0')main(++str);if(*str != '\0')std::cout << *str;--str;return 0;}这种写法编译有警告,但可执行且输出结果正确。
不过本着好学的精神,我自己把它的几个警告一一解决掉了。
2.完美无敌版如下:
#include <iostream>const char *str = "iloveyou";int main(int argc , char** argv = NULL){char ch = (char)argc;if(ch != '\0')main(*((int *)const_cast<char*>(++str))); //const_cast解除const限定if(ch != '\0')std::cout << *str;--str;return 0;}首先给字符串加上const解决第一个警告,但是由于加了const之后,再将str作为参数传递时,接受参数也必须为const,但是main函数参数如上图第二个警告所说,第一个必须为int型,所以先用const_cast去掉str的const限定,将str转为为Int类型,用argc参数接收,然后在函数内部进行强转赋给ch,通过char类型的ch作为判断条件,利用类似子函数递归逆序的方法,实现main函数的递归调用。
正确输出为:
0 0
- 字符串逆序输出与main函数的递归调用
- main函数的递归调用演示,反序输出
- 利用函数递归逆序输出一个字符串
- 字符串逆序的递归函数
- 递归逆序输出字符串
- 递归逆序输出字符串
- 字符串逆序输出,要求调用函数实现
- 逆序输出字符串采用递归的方式
- 递归方法的字符串逆序输出
- 递归算法实现字符串的逆序输出
- 逆序输出字符串(递归实现)
- 递归法逆序输出字符串
- 利用递归逆序输出字符串
- C 递归逆序输出字符串
- 递归实现逆序输出字符串
- 递归函数逆序输出程序
- 字符串的逆序输出
- 字符串的逆序输出
- 从另一个角度观察Spark Shuffle过程
- 表单时间的处理-抛砖引玉
- shell脚本中echo显示内容带颜色
- VirtualBox centos7扩容
- Exception
- 字符串逆序输出与main函数的递归调用
- html页面数据的维护
- iOS利用运行时给分类添加属性
- CSS—盒子模型
- interface和abstract 的区别和相同点
- 第1次做面试官的随谈(一)
- 留下点足迹!
- 计算机名言
- CodeForces 703A Mishka and Game(模拟)