《剑指Offer》面试题:数值的整数次方
2015-08-31 20:34
423 查看
题目
面试题11:数值的整数次方题目:实现函数double Power(double base,int exponent),
求base的exponent次方,不得使用库函数,同时不需要考虑大数问题
/* 面试题11:数值的整数次方 题目:实现函数double Power(double base,int exponent), 求base的exponent次方,不得使用库函数,同时不需要考虑大数问题 */ /*需要考虑的测试用例如下 //base、exponent两者都不为零的情况 base=3 ,exponent=4//基数和指数均为正数 base=-3,exponent=4//基数为负,指数为正 base=3,exponent=-4//基数为正,指数为负 base=-3,exponent=-4//基数、指数均为正 //base、exponent至少有一个为零的情况 base=0,exponent=1 base=0,exponent=-1//特别要注意 base=0,exponent=0 */ #include<stdio.h> bool my_equal(double base,double num){ if(base-num<0.0001&&base-num>-0.0001){ return true; } return false; } //定义一个全局变量,来标志输入是否有效,当输入无效( base=0,exponent=-1//特别要注意 )的时候,该值为true bool g_InvalidInput=false; /* 一般的思路如下 */ double my_Power(double base,int exponent){ g_InvalidInput=false;//初始化为false,目的是为了防止多次调用该函数,g_InvalidInput的标志位被设置为了true,对后面的调用的结果产生一定的影响 //先判断输入是否有效,即判断是否出现了 base=0,exponent=-1这种情况 /*因为base为double型数据,因此不能直接用base==0来判断其是否等于0, 这是因为计算机内表示小数时(包括float和double)都有一定的误差 , 因此判断两个小数是否相等,只能判断他们之差的绝对值是否在一定的范围内 */ if(my_equal(base,0.0)&&exponent<0){ g_InvalidInput=true; return 0.0; } //将0的0次方单独拿出来考虑 if(my_equal(base,0.0)&&exponent==0) { return 1.0; } double result=1.0; int negative=1;//指数是否为负数的标志位 if(exponent<0){ negative=-1; exponent=-exponent; } for(int i=0;i<exponent;i++){ result*=base; } // printf("%lf\n",result); // printf("%lf\n",1.0/result); return (negative==1?result:(1.0/result)); } int main(void){ double base; int exponent; // scanf("%lf",&base);//这里注意的是:对于double类型的输入的格式为:“%lf” // scanf("%d",&exponent); // printf("%lf\n",Power(base,exponent)); printf("%lf\n",my_Power(3.0,4)); printf("%lf\n",my_Power(-3.0,4)); printf("%lf\n",my_Power(3.0,-1)); printf("%lf\n",my_Power(0.0,-1)); printf("%lf\n",my_Power(0.0,1)); printf("%lf\n",my_Power(0.0,0)); return 0; }
高效的改进
可能有人觉得当exponent有点大的时候,采用如下的for循环来计算数值的整数次方不高效for(int i=0;i<exponent;i++){ result*=base; }
于是,就有了如下的改进。
base的exponent次方
当exponent为偶数时等于base的(exponent/2)的平方
当exponent为奇数时等于base的(exponent/2)的平方再乘以一个base
实现代码如下:
#include<stdio.h>
//定义一个全局变量,来标志输入是否有效,当输入无效( base=0,exponent=-1//特别要注意 )的时候,该值为true
bool g_InvalidInput=false;
bool my_equal(double base,double num){
if(base-num<0.0001&&base-num>-0.0001){
return true;
}
return false;
}
/*功能:更高效的完成数值的整数次方的运算
比for(int i=0;i<exponent;i++){ result*=base; }更高效
@param base:基数
@param exponent:指数 且大于等于0
*/
double PowerWithUnsiginedExponent(double base,int exponent){
if(exponent==0){
return 1.0;
}
if(exponent==1){
return base;
}
double result=PowerWithUnsiginedExponent(base,exponent>>1);
result*=result;
if(exponent&0x01){
result*=base;
}
return result;
}
double my_Power(double base,int exponent){
g_InvalidInput=false;//初始化为false,目的是为了防止多次调用该函数,g_InvalidInput的标志位被设置为了true,对后面的调用的结果产生一定的影响
//先判断输入是否有效,即判断是否出现了 base=0,exponent=-1这种情况
/*因为base为double型数据,因此不能直接用base==0来判断其是否等于0,
这是因为计算机内表示小数时(包括float和double)都有一定的误差 ,
因此判断两个小数是否相等,只能判断他们之差的绝对值是否在一定的范围内 */
if(my_equal(base,0.0)&&exponent<0){
g_InvalidInput=true;
return 0.0;
}
//将0的0次方单独拿出来考虑
if(my_equal(base,0.0)&&exponent==0) {
return 1.0;
}
double result=1.0;
int negative=1;//指数是否为负数的标志位
if(exponent<0){
negative=-1;
exponent=-exponent;
}
result=PowerWithUnsiginedExponent( base, exponent);
// printf("%lf\n",result);
// printf("%lf\n",1.0/result);
return (negative==1?result:(1.0/result));
}
int main(void){
double base;
int exponent;
// scanf("%lf",&base);//这里注意的是:对于double类型的输入的格式为:“%lf”
// scanf("%d",&exponent);
// printf("%lf\n",Power(base,exponent));
printf("%lf\n",my_Power(3.0,4));
printf("%lf\n",my_Power(-3.0,4));
printf("%lf\n",my_Power(3.0,-1));
printf("%lf\n",my_Power(0.0,-1));
printf("%lf\n",my_Power(0.0,1));
printf("%lf\n",my_Power(0.0,0));
return 0;
}
相关文章推荐
- 剑指offer-第六章面试中的各项能力之总结
- 剑指offer-第六章面试中的各项能力之总结
- 剑指offer-第六章面试中的各项能力(不用加减乘除做加法)
- 面试题:最长公共前缀
- 作为程序员的硬实力是什么 ?
- LintCode-在O(1)时间复杂度删除链表节点
- 花旗银行-面试总结
- dispay属性详解
- 黑马程序员——38,IO流(字符流)
- 面试题:最长公共子串
- IOS面试
- 花旗软件java开发工程师面试
- 一个百度员工离职时说了一番话,震撼了职场人!
- 如何成为游戏主程
- 方法论——程序员的阿喀琉斯之踵
- 剑指offer-第六章面试中的各项能力(圆圈中剩下的最后数字)
- 剑指offer-第六章面试中的各项能力(圆圈中剩下的最后数字)
- 面试之jsp、Servlet相关知识——生命周期,区别等
- 联咏电子科技(西安)笔试、面试经历
- iOS程序员面试题系列(3)