剑指offer—数值的整数次方

来源:互联网 发布:opencv图像分割python 编辑:程序博客网 时间:2024/05/16 18:58

面试题11:题目:实现函数double power(double base , int exponment) ,求base的exponment次方。不得使用库函数,同时不需要考虑大数问题。

我想刚看到这个问题,很可能好多人都笑了,觉得是很简单的一道题,接下来就拿起笔来直接写了。
例如实现1:

#include<stdio.h>#include<stdlib.h>double Power(double base, int exponent){    double ret = 1;        while (exponent)        {            ret *= base;            exponent--;        }    return ret;}int main(){    double base = 0;    int exponent = 0;    double ret = 0;    printf("please enter a base number:");    scanf("%lf", &base);    printf("please enter a exponent number:");    scanf("%d", &exponent);    ret = Power(base, exponent);    printf("%lf", ret);    system("pause");    return 0;}

这种办法是你最先开始就能想到的,但是我想如果你把这一种方法递给面试官,面试官肯定不会满意的。面试官这个时候会说如果输入的指数小于1的时候怎么办?即是0和负数的情况。上面的代码只解决了大于0的情况。

所以接下来我们就来解决为0或者为负数的情况。

#include<stdio.h>#include<stdlib.h>double Power(double base, int exponent){    double ret = 1;    if (exponent > 0)    {        while (exponent)        {            ret *= base;            exponent--;        }    }    else if (exponent < 0)    {        exponent = (unsigned int)(-exponent);        while (exponent)        {            ret *= base;            exponent--;        }        ret = 1.0/ret;    }    else        ret = 1;    return ret;}int main(){    double base = 0;    int exponent = 0;    double ret = 0;    printf("please enter a base number:");    scanf("%lf", &base);    printf("please enter a exponent number:");    scanf("%d", &exponent);    ret = Power(base, exponent);    printf("%lf", ret);    system("pause");    return 0;}

这样我们就解决了指数的边界情况。

这时候我们解决了指数,当然要考虑一下底数,当底数为0时你怎么解决呢?当底数是零并且指数是负数怎么解决呢?如果我们不对此做特殊处理,就会出现当0做分母时出现问题。在这里,我们当然要把这种错误返回给用户,在这里,我们可以采用返回值,全局代码和异常。面试的时候我们就可以向面试官阐述各种的优缺点,然后讨论选定用哪一种。

#include<stdio.h>#include<stdlib.h>#define EPSINON 0.0000000001double Power(double base, int exponent){    double ret = 1;    if (((base -0.0)>-EPSINON)&&(base-0.0)<EPSINON)    {        if (exponent >= 0)        {            ret = 0.0;            return ret;        }        else            return -1; //这里对于错误清况,我们返回-1。    }    if (exponent > 0)    {        while (exponent)        {            ret *= base;            exponent--;        }    }    else if (exponent < 0)    {        exponent = (unsigned int)(-exponent);        while (exponent)        {            ret *= base;            exponent--;        }        ret = 1.0 / ret;    }    else        ret = 1;    return ret;}int main(){    double base = 0;    int exponent = 0;    double ret = 0;    printf("please enter a base number:");    scanf("%lf", &base);    printf("please enter a exponent number:");    scanf("%d", &exponent);    ret = Power(base, exponent);    printf("%lf", ret);    system("pause");    return 0;}

这里我们要清楚,在这里对double类型的数据和0进行比较时,这时就有一个浮点型类型比较的问题,要定义精度。在这里我们只能判断两个浮点数的差的绝对值是不是再一个很小的范围内。如果两个数相差很小,就可以认为它们相等。

上述过程我们已经考虑的很周详了,但是如果当有一个追求完美效率的面试官,那么他会给我们一种更快的办法。在这里我们需要快速做乘方。

#include<stdlib.h>#include<stdio.h>#define EPSINON 0.0000000001double PowerWithUnsignedExponent(double base, int exponent){    if (exponent == 0)        return 0;    if (exponent == 1)        return base;    double result = PowerWithUnsignedExponent(base, (exponent >> 1));    result *= result;    if ((exponent & 0x1) == 1)    {        result *= base;    }    return result;}double Power(double base, int exponent){    double ret = 1;    if (((base - 0.0)>-EPSINON) && (base - 0.0)<EPSINON)    {        if (exponent >= 0)        {            ret = 0.0;            return ret;        }        else            return -1;    }    unsigned int absexponent = (unsigned int)(exponent);    if (exponent < 0)    {        absexponent = (unsigned int)(-exponent);    }    ret = PowerWithUnsignedExponent(base, absexponent);    if (exponent < 0)    {        ret = 1.0 / ret;    }    return ret;}int main(){    double base = 0;    int exponent = 0;    double ret = 0;    printf("please enter a base number:");    scanf("%lf", &base);    printf("please enter a exponent number:");    scanf("%d", &exponent);    ret = Power(base, exponent);    printf("%lf", ret);    system("pause");    return 0;}

在这里,如当我们输入exponent为32,在在最初那种循环我们需要进行31次乘法运算才行,这样就会让效率低一些。我们可以换一种思路,当我们求32次方时,求得16次方,然后平方一次就可以了,然后16又是8次方再给平方,就这样依次进行下去,我们就可以32次方,只需要5次就可以解决了!是不是效率很高呢。所以我们最后利用递归完成了这一次的优化,在这里对次方除2我们用移位运算来做,然后对指数判断是奇数还是偶数。大家要记得,位运算的运算效率比乘除法的效率要高,所以记得以后碰到乘除法的问题,我们可以考虑用位运算做。

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 应用安装验证码忘了怎么办 大王卡激活码找不到了怎么办 信用卡的激活码找不到怎么办 育碧账号忘了怎么办 uplay八折券丢了怎么办 不小心按到了育碧解绑怎么办 台式电脑连不上网怎么办 重装系统也安装不了cad怎么办 染发灰色偏绿了怎么办 vgm数据填错了怎么办 克里格插值 不符合正态分布怎么办 克里金插值无效的输出范围怎么办 穿完臭袜子要洗手吗不洗怎么办 超敏c反应蛋白117怎么办 钢铁雄心4无模板怎么办 登录 新浪微博登录异常怎么办 微博授权失败怎么办qq uc微博授权失败怎么办 苹果手机无线网坏了怎么办 小米手机wife信号不好怎么办 微博出错了c403怎么办 微信客服没人接怎么办 安装包解析错误怎么办平板 苹果手机新浪免费邮箱用不了怎么办 苹果手机老是弹跳邮箱登陆怎么办 qq长时间不登录上不了怎么办 父母不会说英语怎么办英国签证 美军舰真来台湾怎么办 现役军人回家探亲和人打架怎么办 对四六不懂的人怎么办 赌球小2.5进3球怎么办 皮肤旧伤黑色斑怎么办 小米5c网络不好怎么办 小米去5c卡怎么办 戴尔游匣5577开机黑屏怎么办 三星s6的通知栏拉不下来怎么办 电脑记住密码打不开了怎么办 联想手机升级系统失败了怎么办 日本语言学校申请研究生签证怎么办 在埃塞俄比亚签证过期了怎么办 看完的小说想要卖掉该怎么办