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中的幂运算(幂函数)内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Java二维码登录流程实现代码(包含短地址生成,含部分代码)

    Java二维码登录流程实现代码(包含短地址生成,含部分代码)

    近年来,二维码的使用越来越风生水起,本篇文章主要介绍了Java二维码登录流程实现代码,其中包含短地址生成,有兴趣的可以了解一下。
    2016-12-12
  • java发送内嵌图片邮件

    java发送内嵌图片邮件

    这篇文章主要介绍了java发送内嵌图片邮件,在博客系统中需要邮件服务的功能,仅仅是发送文本内容,现在尝试一下发送内嵌图片邮件,感兴趣的小伙伴们可以参考一下
    2016-01-01
  • SpringBoot jwt的token如何刷新

    SpringBoot jwt的token如何刷新

    这篇文章主要给大家介绍了关于SpringBoot jwt的token如何刷新的相关资料,Json web token(JWT)是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准,需要的朋友可以参考下
    2023-07-07
  • springboot集成es插入和查询的简单使用示例详解

    springboot集成es插入和查询的简单使用示例详解

    这篇文章主要介绍了springboot集成es 插入和查询的简单使用,本文分步骤结合示例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-08-08
  • Spring Batch入门教程篇

    Spring Batch入门教程篇

    这篇文章主要给大家介绍了Spring Batch入门的相关资料,文中介绍的非常详细,对大家具有一定的参考学习价值,需要的朋友们下面跟着小编一起来学习学习吧。
    2017-06-06
  • Java根据key获取枚举值的操作方法

    Java根据key获取枚举值的操作方法

    枚举(enum)算一种“语法糖”,是指一个经过排序的、被打包成一个单一实体的项列表,一个枚举的实例可以使用枚举项列表中任意单一项的值,本文给大家介绍了Java 如何快速根据 key 获取枚举的值,需要的朋友可以参考下
    2024-07-07
  • java微信企业号开发之通讯录

    java微信企业号开发之通讯录

    这篇文章主要为大家详细介绍了java微信企业号开发之通讯录的相关资料,感兴趣的小伙伴们可以参考一下
    2016-06-06
  • Jmeter连接Mysql数据库实现过程详解

    Jmeter连接Mysql数据库实现过程详解

    这篇文章主要介绍了Jmeter连接Mysql数据库实现过程详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-08-08
  • SpringCloud openfeign相互调用实现方法介绍

    SpringCloud openfeign相互调用实现方法介绍

    在springcloud中,openfeign是取代了feign作为负载均衡组件的,feign最早是netflix提供的,他是一个轻量级的支持RESTful的http服务调用框架,内置了ribbon,而ribbon可以提供负载均衡机制,因此feign可以作为一个负载均衡的远程服务调用框架使用
    2022-11-11
  • springboot集成tkmapper及基本使用教程

    springboot集成tkmapper及基本使用教程

    tk.mybatis可以节省程序员的大部分时间,对于程序员来说关于一张表的操作无非就是增删改查,tk.mybatis提供了一些基本操作的SQL语句,比如说按表的主键查询、删除等基本操作,我们接下来就来介绍一些springboot集成tkmapper及基本使用
    2022-11-11

最新评论