首页 > 代码库 > 幂取模
幂取模
求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) { 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; }
这个代码易于理解,但是效率略差于上面的代码(其实也没差多少)。
注:位运算是运算器的基本操作,不需要调用累加器,而乘除是比较复杂的,基于加法运算,需要调用累加器!
幂取模
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。