2021-03-04

库函数 p o w pow pow实现与快速幂

题目:

实现库函数pow(double base, int exp)

解题思路

这道题最朴素的解法如下:

double ans = base;
for(int i = 0; i < exp; i++) {
	ans *= base;
}
return ans;

缺陷

首先,没有考虑到边界条件。显然exp可以为负,当exp为负时base不能为0,且baseexp不能同时为0,因为 0 0 0^0 00没有意义。
其次,算法的时间复杂度太高。总所周知乘法的时间耗费不止一个指令周期,上面的解法需要算 ∣ b a s e ∣ |base| base次乘法。

快速幂

因为 b a s e e x p = b a s e ( e x p 2 ) 2 {base}^{exp} = {base}^{(\frac {exp} 2)^2} baseexp=base(2exp)2,所以可以利用分治的思想:

p o w ( b a s e , e x p ) = p o w ( b a s e , e x p 2 ) ∗ p o w ( b a s e , e x p 2 ) pow(base, exp) = pow(base, \frac {exp} 2) * pow(base, \frac {exp} 2) pow(base,exp)=pow(base,2exp)pow(base,2exp)

从而得到分治思想计算幂次的方法,该方法被称为快速幂

递归版本

public double pow(double base, int exp) {
	if (n == 0) return 1;
	if (n & 1) return pow(base, exp - 1) * a;
	int ans = pow(base, exp >> 2);
	return ans * ans;
}

需要注意到除法运算和取模运算都使用位运算代替,这是因为计算机除法和取模指令耗时高。
当前方法显然比之前的方法要好,因为只进行了 l o g ( e x p ) log(exp) log(exp)次乘法,算法的时间复杂度为 O ( l o g ( e x p ) ) O(log(exp)) O(log(exp))。但是递归版本函数调用耗时较高,而且指数较高时会因为函数调用次数过多导致程序崩溃。

迭代版本

因为 e x p exp exp是整数,可以用二级制 1010001... 1010001... 1010001...来表示。所以快速幂的迭代版本为:

public double pow(double base, int exp) {
	double ans = 1;
	while (exp) {
		if (exp & 1) {
			ans *= base;
		}
		base *= base;
		exp >>= 1;
	}
	return ans;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值