C语言遇到一个很有意思的递归问题

废话不多说,直接上题:

#include<stdio.h>

int fun(unsigned int x)
{
	if((x >> 1) == 0) return x;
	if((x & 1) == 0) return(fun(x/2));
	else return(fun(3*x + 1));
}

int main(void)
{
	printf("x = %d\n", fun(27));
	return 0;
}

问输出是多少?

这咋一看好像是考递归、移位运算、位运算、加减乘除等。好,那就拿纸出来一层层算吧。

方便起见,我就在int fun(unsigned int x)里稍做修改,方便观察x值的变化。

#include<stdio.h>

int fun(unsigned int x)
{
	static unsigned int ucCnt = 0;
	printf("第%d层: x = %d\n", ++ucCnt, x);
	
	if((x >> 1) == 0) return x;
	if((x & 1) == 0) return(fun(x/2));
	else return(fun(3*x + 1));
}

int main(void)
{
	printf("x = %d\n", fun(27));
	return 0;
}

结果:

    所以这要是一层层算的话,会非常花时间。如果笔试遇到类似这样的题目,只有短短的一个小时,显然是不够用的。但如果不是考察计算能力,就只有往技巧这方向去思考问题了。不难看出,在int fun(unsigned int x)里,if((x >> 1) == 0) return x是该函数的递归出口,那么,最终的输出结果会不会始终是1呢?答案是有可能。由于x是unsigned int类型,所以(x >> 1) == 0要成立的话,x的值就只能是0或者1了,而且在fun(unsigned int x)里,return(fun(x/2))是使x的值递减的,return(fun(3*x + 1))是使x的值递增的,所以if((x >> 1) == 0) return x这个递归出口的上一层运算,始终是return(fun(x/2)),发现这一步关键所在后,问题就好解决了。由于x是做÷运算,所以只有当x为0时,return(fun(x/2))传递到下一层时,才会使0传递到递归出口,且return(fun(3*x + 1))里有一个+1的运算,保证了x的值不可能为0,也就是说无论在内部递归了多少层x=0都不会由return(fun(3*x + 1))产生,那就只剩下在递归输入时x的值就是0才会出现输出是0的情况。

综上所述,fun(0) >> 0, fun(大于0) >> 1。

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值