幂取模

求a^b%c的结果,

方法一:

    a*b%c = ((a%c)*b)%c;

代码如下:

int work(int a, int b, int c)
{
    int res = 1;
    for (int i = 0; i < b; i ++) {
        res = res * a % c;
    }
    return res;
}

但是这种方法复杂度太高,不适合大数据运算,下面介绍一种更快的方法。

方法二:

b可以表示成二进制的形式,我们用p数组表示相应位权的数值(或二进制数),用2的指数次方表示位权,则

b = p[i]*2^i + p[i-1]*2^(i-1) + p[i-2]*2^(i-2) + ... + p[1]*2^1 + p[0]*2^0

我们知道相邻位置,高位权是低位权的2倍,所以在p[i] === 1的情况下,相邻两位高位是低位的两倍。

a^b = a^( p[i]*2^i + p[i-1]*2^(i-1) + p[i-2]*2^(i-2) + ... + p[1]*2^1 + p[0]*2^0 )

      = a^( p[i]*2^i ) * ( a^( p[i-1]*2^(i-1) ) ) * ( a^( p[i-2]*2^( i-2 ) ) )*...*( a^( p[1]*2^1 ) ) * (a^(p[0]*2^0))


有上我们知道表达式相邻两位在p[i] === 1的情况下,高位是低位的平方。

即:a^( p[i]*2^i ) =  ( a^( p[i-1]*2^(i-1) ) ) * ( a^( p[i-1]*2^(i-1) ) ) ;

又有上面的表达式我们知道,当p[i] = 0时,a^( p[i]*2^i ) = a ^ 0 = 1;

所以我们只要p[i] = 1的时候,表达式乘以a^( p[i]*2^i )


我们得到下面的代码:


int mod_exp(int a, int b, int c)        a^b%c
{
    int res, t;
    res = 1 % c;
    t = a % c;
    while (b)
    {
        if (b & 1)
        {
            res = res * t % c;
        }
        t = t * t % c;
        b >>= 1;
    }
    return res;
}

因为我们只需要判断相应位置是否为1,我们可以知道二进制数的2^0位的权值为1,则这个是一定是奇数,所以我们可以得到下面的代码:


int mod_exp(int a, int b, int c)       a^b%c
{
    int res, t;
    res = 1 % c;
    t = a % c;
    while (b)
    {
        if (b % 2)
        {
            res = res * t % c;
        }
        t = t * t % c;
        b /= 2;
    }
    return res;
}

这个代码易于理解,但是效率略差于上面的代码(其实也没差多少)。

注:位运算是运算器的基本操作,不需要调用累加器,而乘除是比较复杂的,基于加法运算,需要调用累加器!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值