zoukankan      html  css  js  c++  java
  • 44. log(n)求a的n次方[power(a,n)]

    【题目】

    实现函数double Power(double base, int exponent),求base的exponent次方,不需要考虑溢出。

    【分析】

    这是一道看起来很简单的问题,很容易写出如下的代码:

     C++ Code 
    1
    2
    3
    4
    5
    6
    7
    8
    9
     

    double Power(double base, int exponent)
    {
        
    double result = 1.0;
        
    for(int i = 1; i <= exponent; ++i)
            result *= base;

        
    return result;
    }

    上述代码存在的问题:

    (1) 由于输入的exponent是个int型的数值,因此可能为正数,也可能是负数,上述代码只考虑了exponent为正数的情况。

    (2) 底数为0,指数为负数,则输入非法。

    改进之后代码如下:

    【代码1】

     C++ Code 
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
     

    bool g_bValid = true;

    bool Equal(double num1, double num2)
    {
        
    double gap = 0.00000001;
        
    if (num1 - num2 > -gap && num1 - num2 < gap)
            
    return true;
        
    return false;
    }

    double PowerWithUnsignedExponent(double base, unsigned int exponent)
    {
        
    // T(n) = O(n)
        double result = 1.0;
        
    for (int i = 0; i < exponent; ++i)
            result *= base;
        
    return result;
    }

    double Power(double base, int exponent)
    {
        g_bValid = 
    true;
        
    if(Equal(base, 0.0))
        {
            
    if (exponent < 0)
            {
                g_bValid = 
    false;
            }
            
    return 0.0;
        }

        
    unsigned int absExponent = (unsigned int)exponent;
        
    if (exponent < 0)
            absExponent = (
    unsigned int)(-exponent);

        
    double result = PowerWithUnsignedExponent(base, absExponent);
        
    if (exponent < 0)
            result = 
    1.0 / result;

        
    return result;
    }

    其时间复杂度为O(n),如何进一步改进?

    我们可以用如下公式求a的n次方,其时间复杂度为O(lgn):

    n is even: a^n = a^(n/2)*a^(n/2)

    n is odd: a^n = a^((n-1)/2)*a^((n-1)/2) * a

    改进后代码如下:

    【代码2】

     C++ Code 
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
     

    /*
    n is even: a^n = a^(n/2)*a^(n/2)
    n is odd: a^n = a^((n-1)/2)*a^((n-1)/2) * a
    */

    double PowerWithUnsignedExponent2(double base, unsigned int exponent)
    {
        
    // T(n) = O(lgn)
        if (exponent == 0)
            
    return 1;
        
    else if (exponent == 1)
            
    return base;

        
    double result = PowerWithUnsignedExponent2(base, exponent >> 2);
        result *= result;

        
    if (exponent & 0x1)
        {
            
    // exponent is odd
            result *= base;
        }
        
    return result;
    }

    【参考】

    http://zhedahht.blog.163.com/blog/static/254111742009101563242535/

    个人学习笔记,欢迎拍砖!---by hellogiser

    Author: hellogiser
    Warning: 本文版权归作者和博客园共有,欢迎转载,但请保留此段声明,且在文章页面明显位置给出原文连接。Thanks!
    Me: 如果觉得本文对你有帮助的话,那么【推荐】给大家吧,希望今后能够为大家带来更好的技术文章!敬请【关注】
  • 相关阅读:
    安卓之屏幕适配
    Kotlin入门教程——目录索引
    Kotlin入门(33)运用扩展属性
    Kotlin入门(32)网络接口访问
    Kotlin入门(31)JSON字符串的解析
    Kotlin入门(30)多线程交互
    Kotlin入门(29)任务Runnable
    Kotlin入门(28)Application单例化
    Kotlin入门(27)文件读写操作
    Kotlin入门(26)数据库ManagedSQLiteOpenHelper
  • 原文地址:https://www.cnblogs.com/hellogiser/p/3741850.html
Copyright © 2011-2022 走看看