06 实现数值的整数次方
来源:互联网 发布:python安装pip命令 编辑:程序博客网 时间:2024/05/23 13:03
前言
本博文部分图片, 思路来自于剑指offer 或者编程珠玑
问题描述
思路
书中给出了两种思路
设定输入的基数为base, 幂数为exp
思路一 : 构造一个循环, exp次相乘得到结果
思路二 : 在第一种思路的前提下面, 对于输入进行检查, 增加处理负数的情况 [鲁棒性]
思路三 : 在第二种思路的基础上面, 优化求幂的过程, 将pow(3, 7) –decompose–> pow(3, 4) * pow(3, 2) * pow(3, 1), 缓存base的整数次方的结果, 可以节省很多开销
参考代码
/** * file name : Test27PowImp.java * created at : 11:24:06 AM Jun 5, 2015 * created by 970655147 */package com.hx.test04;public class Test27PowImp { // 实现pow方法 public static void main(String []args) { double base = 3; int exp = 7; double res = pow01(base, exp); Log.log(res); res = pow02(base, exp); Log.log(res); res = pow03(base, exp); Log.log(res); } // 只考虑了exp为正数的情况, 所以不全面, 并且没有考虑base为0的输入 public static double pow01(double base, int exp) { double res = 1.0; for(int i=0; i<exp; i++) { res *= base; } return res; } // 考虑了exp为正负数, base可能为0的输入 public static double pow02(double base, int exp) { if(eq(base, 0.0) ) { return 1.0; } boolean isPos = true; if(exp < 0) { exp = -exp; isPos = false; } double res = 1.0; for(int i=0; i<exp; i++) { res *= base; } if(! isPos) { res = 1/ res; } return res; } // 考虑了exp为正负数, base可能为0的输入 // 优化求幂的过程 public static double pow03(double base, int exp) { if(eq(base, 0.0) ) { return 1.0; } boolean isPos = true; if(exp < 0) { exp = -exp; isPos = false; } double res = powUnsigned(base, exp); if(!isPos) { res = 1/ res; } return res; } // 确保exp为正 计算通常情况下的base^exp // 比循环相乘更优 比如 : 2^32 = (2^16)^2 = ((2^8)^2)^2 = (((2^4)^2)^2)^2 = ((((2^2)^2)^2)^2)^2 // 乘法的话 会计算2*2*2*....*2[32个2] public static double powUnsigned(double base, int exp) { int tmp = exp; int higestOneBit = -1; int res = 1, baseTmp = (int ) base; if(! eq(lastBase, base)) { powCache.clear(); lastBase = base; } while(tmp > 0) { higestOneBit = Integer.highestOneBit(tmp); res = res * getResForHigestOneBit(baseTmp, higestOneBit); tmp -= higestOneBit; } return res; } // 计算base的 higestOneBit, 其中higestOneBit是2的n次方["整数"] // 存在缓存 static double lastBase = -1; static Map<Integer, Integer> powCache = new HashMap<Integer, Integer>(); private static int getResForHigestOneBit(int base, int higestOneBit) { if(higestOneBit == 1) { return base; } if(powCache.containsKey(higestOneBit)) { return powCache.get(higestOneBit); } else { int half = getResForHigestOneBit(base, (higestOneBit >> 1) ); int res = half * half; powCache.put(higestOneBit, res); return res; } } // 判断两个浮点数 是否相等[区间判别] static double minDiff = 0.0000001d; private static boolean eq(double param01, double param02) { if(Math.abs(param01 - param02) < minDiff) { return true; } return false; }}
效果截图
总结
是否是对算法三的计算优化有一种叹为观止的感脚?, 对于固定基数[base]的场景, 只用缓存n个pow的结果, 就能够计算base为基数, exp范围为[0-2^(n+1) ) 之间的数据, 而且灰常快
注 : 因为作者的水平有限,必然可能出现一些bug, 所以请大家指出!
0 0
- 06 实现数值的整数次方
- 数值的整数次方代码实现
- 数值的整数次方Java实现
- 数值的整数次方
- 数值的整数次方
- 数值的整数次方
- 数值的整数次方
- 数值的整数次方
- 数值的整数次方
- 数值的整数次方
- 数值的整数次方
- 数值的整数次方
- 数值的整数次方
- 数值的整数次方
- 数值的整数次方
- 数值的整数次方
- 数值的整数次方
- 数值的整数次方
- 在启动tomcat服务器时候加载一个action的方法
- ubuntu---mysql操作数据表
- hadoop 各类key value分隔符参数
- 2015.12.31
- 安装jdk一次失败发现的问题
- 06 实现数值的整数次方
- 刘亚洲上将:军内积弊如深渊 参谋队伍建树少
- 国际编码与中文字符
- scrollview起始位置如何设置为顶部
- 关于tableview的界面得数据的变化怎么进行刷新的问题
- 几种元素的用法
- 文件下载工具类
- 关于jquery中html()、text()、val()的区别
- Spark修炼之道(高级篇)——Spark源码阅读:第十二节 Spark SQL 处理流程分析