剑指Offer学习总结-数值的整数次方
2018-01-17 21:15
423 查看
剑指Offer学习总结-数值的整数次方
本系列为剑指Offer学习总结,主要是代码案例的分析和实现:书籍链接:http://product.dangdang.com/24242724.html
原作者博客:http://zhedahht.blog.163.com/blog/static/254111742011101624433132/
原作者博客链接有完整的项目代码下载。
数值的整数次方
题目
题目:实现函数 double Power(double base,int exponent), 求 base的exponent 次方不得使用库函数, 同时不需要考虑大数问题。C++中这个函数参数的限制是base不能为负数,并且exponent不能为小数。第一眼看到的解法:
看到题目的第一思路,我们直接使用一个循环利用乘法给base计算exponent次,使用一个变量来迭代结果数值,初值为1
double Power(double base, int exponent) { double result = 1.0; for(int i = 1; i <= exponent;++i) result *= base; return result; }
我们使用简单的数据测试一下即可发现问题,exponent是整数类型,整数可能有整数负数和零。
当我们使用负指数的时候,我们需要将底数求倒数,然后利用指数的绝对值进行叠加,显然这个情况没有考虑。
当指数为0,底数不为0的时候,结果是1。
底数为0,指数也为0,没有实际意义,因此无论是输出 0 还是 1 都是可以接受的。
上边的方式只适用于指数是无符号的类型。
考虑全面的解法:
double Power(double base, int exponent) { //我们釆用全局变量来标识是否出错 我们在外界来判断参数和返回值是否是合法的 g_InvalidInput = false; //考虑 底数是否为0 由于double类型有精度误差 我们不能用==来判断,是否相等,使用equal(实现是判断差值的绝对值在很小的范围内算做等于) if(equal(base, 0.0) && exponent < 0) { g_InvalidInput = true; return 0.0; } //当无符号数(int)和有符号数(unsignedint)进行算数运算时,有符号数(int)会先转换为无符号数(unsignedint), //用补码来表示 再进行相应的算数运算。 是内存中一次存储格式的转换 unsigned int absExponent = (unsigned int)(exponent); //如果是小于0的指数 ,将原数据取负变正 在进行赋值 if(exponent < 0) absExponent = (unsigned int)(-exponent); double result = PowerWithUnsignedExponent(base, absExponent); //如果是小于0的指数 将结果取倒数 if(exponent < 0) result = 1.0 / result; return result; } double PowerWithUnsignedExponent(double base, unsigned int exponent) { double result = 1.0; for(int i = 1; i <= exponent; ++i) result *= base; return result; } //判断是否两个double类型的数值相等 bool equal(double num1, double num2) { if((num1 - num2 > -0.0000001) && (num1 - num2 < 0.0000001)) return true; else return false; }
优化性能的解法:
如果我们碰到的面试官是一个在效率上追求完美的人, 那么他有可能会提醒我们函数 PowerWithUnsignedExponent 还有更快的办法。
计算提高效率的部分,我们可以发现一个数学规律。
an={an/2∗an/2,a(n−1)/2∗a(n−1)/2∗a,n为偶数n为奇数
这个公式很容易用递归来实现。隐藏的终止条件是 指数为1,返回值是底数本身。
double PowerWithUnsignedExponent(double base, unsigned int exponent) { if(exponent == 0) return 1; if(exponent == 1) return base; //规模缩减 double result = PowerWithUnsignedExponent(base, exponent >> 1); result *= result; //如果是奇数,我们需要多乘一次底数 if((exponent & 0x1) == 1) result *= base; return result; }
相关文章推荐
- 剑指Offer学习之面试题11 :数值的整数次方
- 【剑指Offer学习】【面试题11 :数值的整数次方】
- 【剑指Offer】面试题11:数值的整数次方
- 剑指Offer-11.数值的整数次方
- 剑指offer---数值的整数次方(11)
- 【剑指offer】面试题16:数值的整数次方
- 剑指offer面试题11 数值的整数次方 java实现
- 剑指Offer——数值的整数次方
- 剑指offer__04__数值的整数次方
- [剑指offer][面试题11]数值的整数次方
- 剑指Offer学习总结-从1到n整数中1出现的次数
- 剑指offer--数值的整数次方
- 剑指offer编程题Java实现——面试题11数值的整数次方
- 剑指offer--数值的整数次方
- 剑指Offer面试题:10.数值的整数次方
- 【剑指offer】数值的整数次方
- 剑指Offer之 - 数值的整数次方
- 剑指offer-面试题11.数值的整数次方
- 剑指Offer面试题11[数值的整数次方]
- 剑指offer-11:数值的整数次方