Java中如何编写一个数的n次方(幂运算)?

 更新时间:2024年07月13日 15:14:30   作者:拼搏@  
本文介绍了使用pow函数和自定义for循环计算幂的O(n)时间复杂度方法,然后重点讲解了快速幂算法的分治思想,以及从二进制角度的解释,包括如何通过位运算和循环迭代实现高效计算,给出了Java代码实现

本文介绍了使用pow函数和自定义for循环计算幂的O(n)时间复杂度方法,然后重点讲解了快速幂算法的分治思想,以及从二进制角度的解释,包括如何通过位运算和循环迭代实现高效计算,给出了Java代码实现,

一、算法简介

1.使用pow函数和自定义的for循环的时间复杂度为O(n)

/**计算x的y次方**/
//1.使用Pow函数
double res = Math.pow(x,y);
//2.自定义for循环
double res=x;
for(int i=1;i<y;i++){
     res=res*x;
}

2.快速幂的时间复杂度为O(log n)

二、快速幂的思想

(1)从分冶的角度出发,计算 x^{y}

①假设y为偶数,即计算 3^{8}

3^{8}=3^{2*4}=9^{4}=9^{2*2}=81^{2}=6561^{1}

我们将指数 y,每次划分为 \frac{y}{2},上述式子不需要进行8次循环,而只需要三步即可完 成,注 3^{2*4}9^{2*2}是为了让读者好理解,而重复写的。

②假设y为奇数,即计算 3^{11}

3^{11}=3^{1+10}=3*3^{10}=3*9^{5}=3*9^{1+4}=3*9*81^{2}=3*9*6561^{1}

指数部分为奇数是可以化解成(1+偶数)的形式的,这样我们可以把指数为1的底 拿出来当答案来乘,偶数部分同①继续化解即可

伪代码
    x=3,y=10,res=1
   while(指数y不等于0){
    if(指数y为奇数){
        res = res * x //提取底数出来,作为乘积
    }
    y=y/2 //指数二分
    x=x*x //底数平方

}

(2) 从二进制的角度出发

如8的二进制位:8=1000_{2}

二进制转十进制:1000_{2}=1*2^3+0*2^2+0*2^1+0*2^0=8

那么3^8=3^{(1000)_{2}}=3^{1*2^3+0*2^2+0*2^1+0*2^0}=3^{0*2^0}*3^{0*2^1}*3^{0*2^2}*3^{1*2^3}(倒序写)

观察发现:指数部分是由两部分组成,第一部分是0001,第二部分2^0,2^1,2^2,2^3,发现2是循环增大的(用代码x=x*x,循环迭代出来,但是否使用则看二进制位是否为‘1’),由于二进制要么为0要么为1(用代码 y&1==1,来判断)

再举个详细的例子(计算3^{11}):

11=1011

3^{11}=3^{1*2^{0}}*3^{1*2^{1}}*3^{0*2^{2}}*3^{1*2^{3}}=3^{1*1}*3^{1*2}*3^{0*4}*3^{1*8}

伪代码:

 x=3,y=11,res=1

 while( (1011)y从尾往头读取){

  if( (y&1)==1){

     res=res*x;  //二进制位不为0,则相乘

     //如第一个1:res=1*3,    

     //第二个1:res=res*3^2

     //第三个数为0:不相乘,但x是不断平方的,此时是x^4

     //第四个数为1:res=res*3^8  ,注意哦,平方是在if后面

       }

    二进制右移一位

    x=x*x; //依次迭代3^0,3^1,3^2,3^4,3^8................

 }

三、代码实现

   public static double FastPow(int x,int y){
        double res= 1;
        while (y!=0){ 
            if(y%2 == 1){ //指数为奇数,也可以利用位运算:(y&1)==1 (与操作): 判断 n 二进制最右一位是否为 1
                res *= x;
            }
            y=y/2;  //指数循环二分,y>>=1 (移位操作): n 右移一位(可理解为删除最后一位,即除以2)。
            x=x*x;  //底数平分

        }
        return res;
    }

 

到此这篇关于Java中如何编写一个数的n次方(幂运算)?的文章就介绍到这了,更多相关Java中的幂运算(幂函数)内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • mybatis连接数据库实现双表查询

    mybatis连接数据库实现双表查询

    本文主要介绍了mybatis连接数据库实现双表查询,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2024-09-09
  • 关于spring aop两种代理混用的问题

    关于spring aop两种代理混用的问题

    这篇文章主要介绍了关于spring aop两种代理混用的问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-11-11
  • java利用时间格式生成唯一文件名的方法

    java利用时间格式生成唯一文件名的方法

    这篇文章主要介绍了java利用时间格式生成唯一文件名的方法,需要的朋友可以参考下
    2017-01-01
  • 基于Java代码实现支付充值的通用流程

    基于Java代码实现支付充值的通用流程

    本文给大家分享一段java核心代码实现支付充值的通用流程,非常不错,具有参考借鉴价值,感兴趣的朋友一起看看吧
    2016-05-05
  • Java中的static--静态变量你了解吗

    Java中的static--静态变量你了解吗

    Java 中被 static 修饰的成员称为静态成员或类成员。它属于整个类所有,而不是某个对象所有,即被类的所有对象所共享。静态成员可以使用类名直接访问,也可以使用对象名进行访问,.下面我们来详细了解一下吧
    2021-09-09
  • 如何在java中使用Jython

    如何在java中使用Jython

    这篇文章主要介绍了如何在java中使用Jython,由于项目中需要用到Java调用Python的脚本,来实现一些功能,就对jython做了一些了解,通过jython可以实现java对python脚本的调用,需要的朋友可以参考一下
    2022-03-03
  • Java使用EasyExcel动态添加自增序号列

    Java使用EasyExcel动态添加自增序号列

    本文将介绍如何通过使用EasyExcel自定义拦截器实现在最终的Excel文件中新增一列自增的序号列,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-09-09
  • Java面试题冲刺第三天--集合框架篇

    Java面试题冲刺第三天--集合框架篇

    这篇文章主要为大家分享了最有价值的三道java面试题,涵盖内容全面,包括数据结构和算法相关的题目、经典面试编程题等,感兴趣的小伙伴们可以参考一下
    2021-07-07
  • 深入了解Java核心类库--Math类

    深入了解Java核心类库--Math类

    本文是小编最新给大家整理的关于Java中Math类常用方法的知识,通过实例代码给大家介绍的非常详细,感兴趣的朋友一起看看吧,
    2021-07-07
  • 解决执行maven命令时提示Process terminated的问题

    解决执行maven命令时提示Process terminated的问题

    这篇文章主要介绍了解决执行maven命令时提示Process terminated的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-09-09

最新评论