C语言学习-递归4

【问题】:模取幂运算 计算a^b mod c

【思路】:

                                     /  (((a ^ (b / 2 )) % mod) ^ 2 ) % mod   

    b
% 2 = 0 (a ^ b) % mod =|           

                                     (((a
^ (b / 2 )) % mod) ^ 2 * a) % mod  b % 2 = 1

【即】:根据上面的式子,可以直接用递归,也就是从顶向下来计算,或者我们自底而上来计算.
从上面的式子中我们注意到,我们是按b%2的情况来递归地计算a^b%mod的,于是,在整个递归过程中,我们是按b的二进制展开形式来计算的,如果我们实现得到了b的二进制形式,我们就可以自底而上的计算a^b%mod了.

【解决方法】:/****************************************************/
//                   模取幂运算 计算a^b mod c
//                  利用公式   
//                  (a*b)mod(c) = ((a mod c )*b)mod c                                                                      
/****************************************************/
int a_b_Mod_c(int a, int b, int c)
{//前提 a b c 都是正数
    int digit[32];
    
int i, k, resualt = 1;
    i 
= 0;
    
while(b)//把b化成2进制
    {
        digit[i
++= b%2;
        b 
>>= 1;
    }

    
//计算(a^b) mod c
    for(k = i-1; k >= 0; k--)
    
{
        resualt 
= (resualt * resualt) % c;
        
if(digit[k] == 1)
        
{
            resualt 
= (resualt * a) % c;
        }

    }


    
return resualt;
}

【延伸】:

三进制的:int a_b_Mod_c(int a, int b, int c)
{
//前提 a b c 都是正数
    int digit[32];                 
   
int i, k, resualt = 1;         
    i
= 0;
   
while(b)//把b化成3进制
    {
        digit[i
++] = b%3;
        b
/=3 ;
    }
   
   
//计算(a^b) mod c
    for(k = i-1; k >= 0; k--) = (resualt * resualt * resualt) % c;    //因为基数是3,所以要3个resualt相乘意            
        if(digit[k] == 1)
        {
            resualt
= (resualt * a) % c;     //因为3进制会出现0,1,2,当为1时就乘一个a             
        }
       
else if(digit[k]==2)
        {
            resualt
= (resualt *a*a) % c;//当为2时乘两个a
        }
    }
   
   
return resualt;
}

{resualt

四进制的:

int a_b_Mod_c(int a, int b, int c)
{
//前提 a b c 都是正数
    int digit[32];                  
   
int i, k, resualt = 1;         
    i
= 0;
   
while(b)//把b化成4进制
    {
        digit[i
++] = b%4;
        b
/=4;
    }
   
//计算(a^b) mod c
    for(k = i-1; k >= 0; k--)
    {
        resualt
= (resualt * resualt*resualt*resualt) % c;    //基数是4,4个resualt       
        if(digit[k] == 1)
        {
            resualt
= (resualt * a) % c;     //会出现0,1,2,3              如上
        }
       
if(digit[k]==2)
            resualt
= (resualt * a *a) % c; //为2时 如上
        if(digit[k]==3)
            resualt
= (resualt * a * a * a) % c;  //为3时  如上
    }
   
   
return resualt;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值