C语言快速幂取模算法小结

本文实例汇总了C语言实现的快速幂取模算法,是比较常见的算法。分享给大家供大家参考之用。具体如下:

首先,所谓的快速幂,实际上是快速幂取模的缩写,简单的说,就是快速的求一个幂式的模(余)。在程序设计过程中,经常要去求一些大数对于某个数的余数,为了得到更快、计算范围更大的算法,产生了快速幂取模算法。我们先从简单的例子入手:求abmodc

算法1.直接设计这个算法:

int ans = 1;
for(int i = 1;i<=b;i++)
{
  ans = ans * a;
}
ans = ans % c;

缺点:这个算法存在着明显的问题,如果a和b过大,很容易就会溢出。

我们先来看看第一个改进方案:在讲这个方案之前,要先看这样一个公式:ab mod c = (a mod c)c mod c

于是不用思考的进行了改进:

算法2.改进算法:

int ans = 1;
a = a % c; //加上这一句
for(int i = 1;i<=b;i++)
{
  ans = ans * a;
}
ans = ans % c;

读者应该可以想到,既然某个因子取余之后相乘再取余保持余数不变,那么新算得的ans也可以进行取余,所以得到比较良好的改进版本。

算法3.进一步改进算法:

int ans = 1;
a = a % c; //加上这一句
for(int i = 1;i<=b;i++)
{
  ans = (ans * a) % c;//这里再取了一次余
}
ans = ans % c;

这个算法在时间复杂度上没有改进,仍为O(b),不过已经好很多的,但是在c过大的条件下,还是很有可能超时,所以,我们推出以下的快速幂算法。

算法4.快速幂算法:

快速幂算法依赖于以下明显的公式:

int PowerMod(int a, int b, int c)
{
  int ans = 1;
  a = a % c;
  while(b>0) {
    if(b % 2 = = 1)
    ans = (ans * a) % c;
    b = b/2;
    a = (a * a) % c;
  }
  return ans;
}

本算法的时间复杂度为O(logb),能在几乎所有的程序设计(竞赛)过程中通过,是目前最常用的算法之一。

相信本文所述对大家算法设计的学习有一定的借鉴价值。

(0)

相关推荐

  • C语言实现的排列组合问题的通用算法、解决方法

    尽管排列组合是生活中经常遇到的问题,可在程序设计时,不深入思考或者经验不足都让人无从下手.由于排列组合问题总是先取组合再排列,并且单纯的排列问题相对简单,所以本文仅对组合问题的实现进行详细讨论.以在n个数中选取m(0<m<=n)个数为例,问题可分解为: 1. 首先从n个数中选取编号最大的数,然后在剩下的n-1个数里面选取m-1个数,直到从n-(m-1)个数中选取1个数为止. 2. 从n个数中选取编号次小的一个数,继续执行1步,直到当前可选编号最大的数为m. 很明显,上述方法是一个递归的过程,也

  • ASP使用FSO读取模板的代码

    m_Root是文件名,可以使用相对路径. 调用调用示例: Response.Write(LoadFile("Test.htm")) Function LoadFile(m_Root) Dim Filename,fso,hndFile Filename = m_Root If Right(Filename, 1)<>"/" And Right(Filename, 1)<>"\" Then Filename = Filenam

  • C语言实现排序算法之归并排序详解

    排序算法中的归并排序(Merge Sort)是利用"归并"技术来进行排序.归并是指将若干个已排序的子文件合并成一个有序的文件. 一.实现原理: 1.算法基本思路 设两个有序的子文件(相当于输入堆)放在同一向量中相邻的位置上:R[low..m],R[m+1..high],先将它们合并到一个局部的暂存向量R1(相当于输出堆)中,待合并完成后将R1复制回R[low..high]中. (1)合并过程 合并过程中,设置i,j和p三个指针,其初值分别指向这三个记录区的起始位置.合并时依次比较R[i

  • 组策略中的审核策略提示 Windows无法读取模板信息的解决方法

    组策略出现"windows无法读取模板信息"是因为删除了Win2000/XP/2003中的guest账号.解决办法: 1.注册表有备份.很简单,恢复备份就是了. 组策略出现"windows无法读取模板信息"是因为删除了Win2000/XP/2003中的guest账号.解决办法: 1.注册表有备份.很简单,恢复备份就是了. 2.注册表没有备份. 下面是我从windows server 2003上倒出来的两个注册表项,复制另存为 guest修复.reg,导进去即可. 复

  • 对C语言中递归算法的深入解析

    许多教科书都把计算机阶乘和菲波那契数列用来说明递归,非常不幸我们可爱的著名的老潭老师的<C语言程序设计>一书中就是从阶乘的计算开始的函数递归.导致读过这本经书的同学们,看到阶乘计算第一个想法就是递归.但是在阶乘的计算里,递归并没有提供任何优越之处.在菲波那契数列中,它的效率更是低的非常恐怖. 这里有一个简单的程序,可用于说明递归.程序的目的是把一个整数从二进制形式转换为可打印的字符形式.例如:给出一个值4267,我们需要依次产生字符'4','2','6',和'7'.就如在printf函数中使用

  • C++快速幂与大数取模算法示例

    一.快速幂 其实就是求(a^b)% p ,(其中a,b,p都比较大在int范围内)这类问题. 首先要知道取余的公式: (a*b)%p=(a%p*b%p)%p . 那么幂不就是乘机的累积吗,由此给出代码: int fast(int a,int b,int p) { long long a1=a,t=1; while(b>0) { if(b&1) /如果幂b是奇数多乘一次,因为后边会除2变偶数,(7/2=3) t=(t%p)*(a1%p)%p; a1=(a1%p)*(a1%p)%p; b/=2;

  • php字符串截取中文截取2,单字节截取模式

    //中文截取2,单字节截取模式 function cn_substr($str,$slen,$startdd=0){     $restr = "";     $c = "";     $str_len = strlen($str);     if($str_len < $startdd+1) return "";     if($str_len < $startdd + $slen || $slen==0) $slen = $str

  • js取模(求余数)隔行变色

    复制代码 代码如下: <html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><title>js取模隔行变色</title><script type="text/javascript"

  • C语言快速幂取模算法小结

    本文实例汇总了C语言实现的快速幂取模算法,是比较常见的算法.分享给大家供大家参考之用.具体如下: 首先,所谓的快速幂,实际上是快速幂取模的缩写,简单的说,就是快速的求一个幂式的模(余).在程序设计过程中,经常要去求一些大数对于某个数的余数,为了得到更快.计算范围更大的算法,产生了快速幂取模算法.我们先从简单的例子入手:求abmodc 算法1.直接设计这个算法: int ans = 1; for(int i = 1;i<=b;i++) { ans = ans * a; } ans = ans %

  • Java语言实现快速幂取模算法详解

    快速幂取模算法的引入是从大数的小数取模的朴素算法的局限性所提出的,在朴素的方法中我们计算一个数比如5^1003%31是非常消耗我们的计算资源的,在整个计算过程中最麻烦的就是我们的5^1003这个过程 缺点1:在我们在之后计算指数的过程中,计算的数字不都拿得增大,非常的占用我们的计算资源(主要是时间,还有空间) 缺点2:我们计算的中间过程数字大的恐怖,我们现有的计算机是没有办法记录这么长的数据的,所以说我们必须要想一个更加高效的方法来解决这个问题 当我们计算AB%C的时候,最便捷的方法就是调用Ma

  • C语言取模取整的深入理解

    目录 一:四大取整 1.1. 0向取整 1.2.  -∞取整( 地板取整) 1.3. +∞取整 1.4. 四舍五入取整 1.5. 例子汇总 二:取模 / 取余 2.1. 概念 2.2. 示例(C和Python) 2.3. 取余和取模一样吗? 2.4. 计算数据同符号 2.5. 计算数据不同符号 2.6. 总结 一:四大取整 1.1. 0向取整 看代码: #include <stdio.h> int main() { //本质是向0取整 int i = -2.9; int j = 2.9; pr

  • Java实现5种负载均衡算法(小结)

    目录 概念 轮询算法 加权轮询法 加权随机法 随机法 IP_Hash算法 概念 负载均衡是将客户端请求访问,通过提前约定好的规则转发给各个server.其中有好几个种经典的算法,下面我们用Java实现这几种算法. 轮询算法 轮询算法按顺序把每个新的连接请求分配给下一个服务器,最终把所有请求平分给所有的服务器. 优点:绝对公平 缺点:无法根据服务器性能去分配,无法合理利用服务器资源. package com.monkeyjava.learn.basic.robin; import com.goog

  • C语言完整实现12种排序算法(小结)

    目录 1.冒泡排序 2.插入排序 3.折半插入排序 4.希尔排序 5.选择排序 6.鸡尾酒排序 7.堆排序 8.快速排序 9.归并排序 10.计数排序 11.桶排序 12.基数排序 1.冒泡排序 思路:比较相邻的两个数字,如果前一个数字大,那么就交换两个数字,直到有序.时间复杂度O(n^2),稳定性:这是一种稳定的算法.代码实现: void bubble_sort(int arr[],size_t len){ size_t i,j; for(i=0;i<len;i++){ bool hasSwa

  • C语言中四种取整方式,取余/取模运算以及负数取模问题详解

    目录 零向取整.负无穷向取整.正无穷向取整.四舍五入取整 总结 零向取整.负无穷向取整.正无穷向取整.四舍五入取整 如果将一个浮点数赋值给整形,只会保存整数位: 这种取整方式为零向取整,C语言默认采用的是这种方式 C语言中也有对应的零向取整函数: 同理还有一种函数是负无穷大取整: 它的取整方案是向负无穷大取整: 有地板取整,当然也有正无穷大取整的函数: 它的取整方式是向正无穷大取整: 最后,还有四舍五入取整的函数: 取模/取余 取模概念: 如果a和d是两个自然数,d非零,可以证明存在两个唯一的整

  • C语言编程题杨氏矩阵算法快速上手示例详解

    目录 题目概要 一.解题思路 二.具体代码 题目概要 有一个数字矩阵,矩阵的每行从左到右都是递增的,矩阵从上到下都是递增的,请编写程序在这样的矩阵中查找某个数字是否存在? 一.解题思路 对于查找一个数组中元素是否存在,很多同学第一想法就是从头到尾遍历一遍.这样的想法优点是代码简单且无脑容易上手,但是这样的缺点也很明显,比如是m *n的数组,你从头到尾遍历,最坏情况要找m *n次.题目给的相关条件比如从左向右递增,从上向下递增你也完全没有使用,这样的暴力求解显然不是我们想看到的 我们来介绍一种方法

  • C语言编程深入理解取整取余取模问题示例分析

    目录 1. 取整问题 1.0向取整(C语言默认的取整方案) 2.地板取整(向负无穷的方向取整) 3.天花板取整(向+无穷的方向取整) 4.四舍五入取整 汇总例子 2.取模问题  1.余数的定义 2.两种余数 3.为什么会有这种现象? 3.区分取余与取模 1.取余与与取模的本质区别 2.理解链 3.同符号与不同符号 1.同符号: 2.不同符号 1. 取整问题 1.0向取整(C语言默认的取整方案) #include<stdio.h> #include<windows.h> int ma

  • Python实现求解斐波那契第n项的解法(包括矩阵乘法+快速幂)

    斐波那契数列 首先我们来定义一下斐波那契数列: 即数列的第0项: 算法一:递归 递归计算的节点个数是O(2ⁿ)的级别的,效率很低,存在大量的重复计算. 比如: f(10) = f(9) + f(8) f(9) = f(8) + f(7) 重复 8 f(8) = f(7) + f(6) 重复 7 时间复杂度是O(2ⁿ),极慢 def F1(n): if n <= 1: return max(n, 0) # 前两项 return F1(n-1)+F1(n-2) # 递归 算法二:记忆化搜索 开一个大

随机推荐