• 算法之数值的整数次方


    要求:实现特定库函数pow.

    解决思路:首先常规的解法大家肯定都会,这里主要是一种高效而且很全面的方法。我们要考虑如果输入的指数小于1,也就是零和负数的时候,怎么办呢?

    这样办,可以先对指数求绝对值,然后算出次方的结果后,再取倒数。那么,问题来了,底数是0的时候,0没有倒数啊,假如你对0求了倒数,那岂不是让程序出错。
    为了不使程序出错,这里做一下特殊处理。当底数为0而且指数是负数的时候,我们设立一个布尔型的全局变量,出错时,全局变量为true,返回值为0;

    那么不出错的时候,全局变量也就是false了。

    代码中用到的公式说明:如果输入的指数是exponent为32,则在函数powerwithunsignedexponent的循环中需要做31次乘法。但是我们其实可以不用这么多次的。
    如何做?平方的思想!如果你要求2的8次方,那么在算到2的4次方的时候,把2的4次方平方一下,就得到2的8次方。

    同理,若求2的16次方,直接把2的8次方平方一下,那么,是不是就少了很多次的乘法步骤呢。

    必然,这就是平方的强大之处。所以有如下的公式,我们直接用就好了。

    求a的n次方:

    核心代码
    '''

    bool g_invalidinput=false;
    double  power(double base,int exponent)
    {
     g_invalidinput=false;//全局变量
     if((equal(base,0,0)&(exponnent<0)
    {
       g_invalidinput=true;
       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;
     double powerwithunsignedexponent(int 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)//判断奇偶性,如果为奇,那么还要乘以base.
         return result*base;
      return result;//若为偶,平方后直接输出即可
    

    整体代码(包含测试):
    '''

    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    #include<iostream>
    using namespace std;
    double powerwithunsignedexponent(double base, unsigned int exponent);
    bool g_invalidinput = false;//有效位设为false。
    bool equal(int num1, int num2)//判断两数是否相同
    {
    if ((num1 - num2 > -0.0000001) && (num1 - num2 < 0.0000001))
    	return true;
    else
    	return false;
    }
     double power(double base, int exponent)//考虑到特殊情况
     {
    g_invalidinput = false;
    if  (equal(base,0.0) && exponent < 0)//底数为0,指数为负数的情况
    {
    	g_invalidinput = true;//出错时为true
    	return 0.0;//返回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;
    
       }
      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)//判断奇偶性,如果为奇,那么还要乘以base.
    		result *= base;
    	return result;//若为偶,平方后直接输出即可
       }
     void test(const char* testname, double base, int exponent, double expectedresult, bool expectedflag)
    {
    double result = power(base, exponent);
    if (equal(result, expectedresult) && g_invalidinput == expectedflag)
    	std::cout << testname << " passed" << std::endl;
    else
    	std::cout << testname << "failed" << std::endl;
    }
    int main(int argc, char* argv[])
    {
    test("test1", 3, 2, 9,false );
    test("test2", -2, 3, -8, false);
    test("test3", 0, -1, 0, true);//底数为0,指数为负数的时候,特殊处理
    }
    学习让我快乐,工作让我快乐。学习和工作都是为了更好的生活!
  • 相关阅读:
    Spring中的一些常用接口
    ApplicationContextAware的作用
    用spring的 InitializingBean 的 afterPropertiesSet 来初始化
    虚拟机扩容(/dev/mapper/centos-root 空间不足)
    AJAX
    Git
    jQuery
    JS
    JS
    jQuery
  • 原文地址:https://www.cnblogs.com/xyuanzi/p/13205432.html
Copyright © 2020-2023  润新知