编程珠玑习题第四章第九题的感想
2012-12-28 14:42
239 查看
如题:
将如下递归代码改写成非递归形式
int exp(int x, int n) {
if ( n == 0) {
return 1;
} else if (n % 2 == 0) {
return exp (x, n / 2) * exp(x, n / 2);-------------------------(1)
} else {
return x * exp(x,n-1);---------------------(2)
}
}
分析:
递归处理式(1),(2)是按n的奇偶性来分别处理的,并且对n为奇数时要进行的下一个子问题中的n = n-1,由n为奇数知,n= n-1必定为偶数,所以(2)执行后的下一步递归式中执行的必定是(1)。
(1)执行的下一步递归是n = n / 2; 由于n为偶数,所以必定可以整除。然而,由式(1)引发的下一步递归究竟到达(1)(2)中的哪一个就要看n/2的奇偶性了
将n表示成二进制数,n为奇数时执行(2)相当于将n末尾的1清掉,接着执行递归(1)得到n>>1的递归参数,再下一步执行(1)还是(2)得看n>>1的末位是否为1了(即n>>1的奇偶性)。
具体分析一个实例:n = 7时, 上述递归过程计算x^7可以看成 x*(x*(x)^2)^2, 递归的实际计算过程如下:(x), (x) ^2, x*(x)^2 ,(x*(x)^2)^2, x*(x*(x)^2)^2,递归的调用轨迹可以用(2)(1)(2)(1)(2)然后到"return 1“,一步步退出递归栈了。我们可以发现以上这两个序列和n用二进制表示的莫大关联:7
= 0111B, 0111B 末位为1 因此开始调用递归式(2), 由分析1知,(2)调用后的下一步递归为(1),则011 = (0111-1)/ 2; 再下一步递归式按照011 % 2==1 知应该为(2)。。。。。这样就和(2)(1)(2)(1)(2)相吻合。
综上所示,我们完全可以根据n的二进制表示中各位的值(0或者1)来推断递归的轨迹,从而写出上述递归程序的非递归算法:
result = 1;
if( n == 0)
return 1;
tag = 31;
while( (1 << tag) & n ! = 0) tag--;//找到n的二进制表示中最高位所在的位号
while(tag >=0) {
if ((1<<tag) & n !=0) {
result *= x;
result = result * result;
} else {
result = result * result;
}
tag--;
}
return result;
相关文章推荐
- 编程珠玑 - 第四章习题
- 编程珠玑第二版第四章习题(Java)
- 《编程珠玑》读书笔记4------------第四章部分习题及个人答案
- 自考本科《计算机网络原理》课后习题参考答案(第四章)
- 《Python核心编程》第二版课后习题——第四章(记录自己做的习题,可能有误)
- 编程珠玑之第一章习题8:包含区号800、877,888情况下的排序测试用例
- 《编程珠玑》习题练习In Python——第二章 啊哈!算法
- 快学Scala习题解答—第四章 映射和元组
- 编程珠玑第二章习题2
- 算法竞赛入门经典第四章习题4-2 Squares UVA - 201
- 全国计算机等级考试二级C++第四章编程习题参考解答
- 数据结构与算法分析课后习题第四章(4)
- 统计建模与R软件第四章习题…
- 2008秋-计算机软件基础-第四章习题参考答案 P131 ,习题4,5
- 《Python编程——从入门到实践》第四章部分习题解
- 龙书D3D11章节习题答案(第四章)
- think in java 第四章 习题答案
- java程序设计基础_陈国君版第五版_第四章习题
- 快学Scala习题解答—第四章 映射和元组
- 【算法导论(第三版)】第四章部分习题代码