快速幂(java)

必备的数学知识

对于

加法有(a+b)%c=((a%c)+(b%c))%c

则乘法也有(ab)%c=((a%c)(b%c))%c

//可以代入数去实验

问题引入

我们用程序去计算2的3次方显然等于8,但2的1000次方呢,显然结果是越界,编译器器会报错或输出一个0

对于大数运算,外面采用快速幂的方式进行降低时间复杂度的运算

例如计算2的n次方并对2019取模的值(n可以取大数)

1. 递归法

核心递归式

a的n次方对c取余

1.为奇数时=a*(a的n-1次方)%c;=(a%c*(a的n-1次方)%c)%c
2.为偶数时=(a的n/2次方)*(a的n/2次方)%c

代码实现

public class fushumi {
    public static void main(String[] args) {
        //计算a的n次方再对c取余



        Scanner scanner = new Scanner(System.in);
        int n=scanner.nextInt();//计算n次方
        long c=scanner.nextLong();//结果所需取的余数
        long res=qp(2,n,c);
        System.out.println(res);
    }
    public static long qp(int a,long n,long c){
        if (n==1){//递归出口
            return a%c;
        }
        if ((n&1)==1){//指数为奇数
            return (a%c*qp(a,n-1,c)%c)%c;
        }else{//指数为偶数
            long mid=qp(a,n/2,c)%c;
            return mid*mid;
        }
    }

}

2. 非递归实现(扩大底数法)

核心递推式

a^n=a*a^(n-1);//奇数
a^n=(a*a)^(n/2);//偶数

代码实现

public class fushumi {
    public static void main(String[] args) {
       //计算a的n次方再对c取余
        //非递归实现
        Scanner scanner = new Scanner(System.in);
        int n=scanner.nextInt();//计算n次方
        int ans=1;
        long a=2;//求2的n次方
        long c=scanner.nextLong();//结果所需取的余数
        while (n>0){//指数为奇数
            if ((n&1)==1){
                ans*=a%c;
                n--;//指数减一变为偶数
            }
            a%=c;
            a=(a*a)%c;//底数翻倍,
            n>>=1;//指数减半
        }
        System.out.println(a);

    }

}

此处递推式以指数形式增加

 a=(a*a)%c;//底数以指数形式翻倍
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值