C++递归入门
T1:读入x,求x的各位位数之和
常规思路:
int x,s = 0;
cin >> x;
while (x){
s += x % 10;//每次取最后一位
x /= 10;//除去个位
}
递归思路:
int digitSum(int x){
if (!x) return 0;// !x与x==0等价
return x % 10 + digitSum(x / 10);
}
递归就是在一定的条件下不断调用自身函数,直到条件不满足从而一层层迭代返回上一层。举个栗子,x = 233;
递归的过程是 digitSum(233)-> digitSum(23)->digitSum(2)->digitSum(0);当前位的x = 0 时,我们已不满足接着继续递归的条件了,开始往上一层返回,digitSum(2)的贡献值是 2,它其实是最高位的数值。再返回到digitSum(23),此时的x%10是3,而digitSum(2)的值是2 ,所以digitSum的值是5。再往上返回到digitSum(233),此时x % 10 = 3,不难理解digitSum(23)是已经算好的23的位数之和。
T2:求阶乘
常规思路:会for的人都会阶乘;
递归思路:
int f(int x){
if (x == 1) return 1;
return x * f(x - 1);
}
这里用递归写是为了加深对递归的理解。递归其实很像是一个逆向思维反向求解的过程,按照我们的思路来,如果我们想知道x!则需要先知道(x - 1)!;而想知道(x - 1)!则需要先知道(x - 2)!,这样一层层往下求,而我们都知道1!是1,所以当递归到x = 1的时候,我们就可以往上返回
知道1!就可以算2!,一层层回去知道计算出x!;
T3:转进制(16进制)
常规:略;
递归:
void cput(int x)
{
if (x > 9) printf("%c",x - 10 + 'A');
else printf("%d",x);
}
void trans(long long x)
{
if (!x) return;
trans(x / 16);
cput(x % 16);
}
数学上的16进制转换,都是先将x%16,得到一个数,再把x/16;反复这样操作,然后讲每次取模后的数倒序写出来得到的就是想要的16进制数。但在计算机上有一个问题,我们没办法自由的讲这些数直接翻转(数组的知识倒是可以解决,不过还没学),所以这个时候递归就可以派上用场。既然我们输出的结果是倒序的,那我们可以深入到最内部的层次再开始输出。比如x = 18的时候:
x = 18 x %16 = 2, x/=16 = 1;
x = 1,x %16 = 1, x/=16 = 0;
然后倒着往回写得到0x12。
递归: trans(18)-> trans(1)-> trans(0)
然后回溯(就是往回跳), trans(1)的时候输出1,trans(18)的时候输出2,这就就实现了反转操作。
递归是一种很巧妙的思路,希望这篇粗糙的blog可以帮助同学们理解递归(第一次写blog,写的不好轻喷)。
会单步调的同学可以试着抄一写递归的代码,然后单步调看代码是怎么运行的。