《算法基础》——2.3 求幂运算

2.3 求幂运算

有时程序需要计算某数的正整数次幂,这在该幂指数不大时容易完成。例如,73可以通过计算7×7×7很容易地得到结果343。对于较大的幂,例如7102×187×291,这种计算过程是十分缓慢的。
注 计算较大的幂如7102×187×291可能很缓慢。但如果不是这种求幂运算在某些重要密码学中得到应用,人们也许不会十分关心它。
幸运的是,有一种较快的方法来执行这种运算。这种方法基于乘方运算的两个关键法则:

当这个幂是二次幂时,第一个法则可以迅速地计算出A的幂。
第二个法则能将这些A的幂结合以产生想要的结果。
以下伪代码展示了这个算法:

例如要计算出76。首先算法计算出71、72、74。由于下一个指数8比所需的6大,因此算法停止。

接下来算法使用第二个法则来从已经产生的二次幂中生成76。如果将6看作2的幂的和,6=2+4。使用第二个法则,得到76=72×74=49×2 401=117 649。
执行这个运算进行两次乘法来计算72和74再加上一次乘法来获得最终结果,即总共进行三次乘法运算。这比简单计算7×7×7×7×7×7进行了更少的乘法运算,但在本例中这只是一个小小的不同。
更普遍地,对于指数P,算法进行log(P)次运算来得到A的P次幂。然后算法检验A的二进制位数来确定它应当将其中的哪些乘在一起以获得最终结果。(如果P的二进制位数是1,那么最终的结果应当包含2的相应幂。在前例中,6的二进制表示是110,因此需要计算2的二次幂和四次幂,即22和24。)
在二进制中,数值P有log2(P)位,因此总共的运行时间复杂度是O(log P)+O(log P)=O(log P)。即使P为一百万,log(P)大约只有20,因此这个算法需运行20步左右(至多40次乘法)。这比一百万要小得多。
这种算法的一个限制是当指数很大时,幂增长得过快。即使一个如7300这样“小”的值也有254个十进制位。这意味着用来计算大指数幂庞大数相乘的过程是缓慢的,并且需要大量计算空间。
幸运的是,这种庞大的幂运算的最常见应用是加密算法,这种算法的运算限制在某个模中。尽管这个模通常较大,但仍能限制住运算数和结果的大小。例如如果某模有100位,两个100位数的积就不会大于200位。那么,接下来可以再次用这个模来得到一个不大于100位的结果。虽然用模将每一个数减小使得每步运算稍微变慢,但也意味着可以计算几乎无限大的值。

时间: 2024-08-30 06:14:08

《算法基础》——2.3 求幂运算的相关文章

《算法基础》——导读

**前言**算法是使高效的程序成为可能的方法.它们解释了如何排列记录.搜索项.计算数值(比如质因子分解).查找一个街道网络中的最短路径.确定可能通过通信网络的最大流.算法好坏的差别可能意味着是在一秒.一个小时内解决问题,还是永远也不能解决问题.学习算法使你能建立有用的方法工具来解决具体的问题.它能帮助你理解在不同的情况下,哪个算法是最有效的,所以对于一个特定的问题,你就能选择最适合的算法.对某些数据而言性能优异的算法可能对其他的数据而言表现糟糕.所以知道如何选择一个最适合当前情况的算法是很重要的

《算法基础》——2.4 有关素数的运算

2.4 有关素数的运算 众所周知,一个素数是一个大于1的自然数(一个比0大的整数),它的因数只有1和它本身.一个合数是一个大于1并且非素数的自然数.素数在某些应用中起到重要的作用,在这些应用中素数的特质使得它们能够使特定程序变得简单或繁琐.例如,某些加密程序使用两个大素数的积来保证安全性.将一个由两个大素数相乘得到的数分解成两个大素数是十分困难的,而正是这个事实保证了算法的安全性.以下章节将讨论一些处理素数的常见算法.2.4.1 寻找素数因子寻找一个数的素因子最显而易见方法是尝试将这个数用比其小

c++-UVa1374快速幂运算迭代深搜法 ,C++初学者,求优化方法

问题描述 UVa1374快速幂运算迭代深搜法 ,C++初学者,求优化方法 这是我的代码,优化过几次,但是还是很慢很慢,求大神给优化途经,就是在我的代码的进行优化 #include #include #include #include using namespace std; bool search(int,set&,int dep,int); int MAX=1; int tempMax; int main() { sets;int n; for(n=2;n!=1000;++n) { s.cle

设计-计算n位数为止的3的最大幂运算

问题描述 计算n位数为止的3的最大幂运算 对于一个正整数n(0<n<80),写一个输出n位数以内最大的3的幂运算例 输入1输出9 输入2输出81 输入6输出531441 输入60输出436673502879206784130402698570834024654748577491697818855443 以下是我自己写的程序 #include<stdio.h>#include<string.h>int main(void){ int insum=1; char m[999

Python中比较特别的除法运算和幂运算介绍_python

不管是啥语言都离不开加减乘除这些算法,但是在Python里面你知道这些符号代表什么运算吗? "/"这个是除法运算,那么这个"//"呢?"*"这个是乘法运算,那么这个"**"呢?下面来一一介绍下. "//"运算 除法运算符是"/",这个人人皆知道,但是这个二元运算符"/"求出来的结果都是取决于操作数本身的,比如: 复制代码 代码如下: 20 / 3 6 20 / 3.0

c语言基础问题,求大神解答

问题描述 c语言基础问题,求大神解答 输入10个整数,使其各数顺序向后移动m个位置,如1.2.3.4.5.6.7.8.9.10移动后为7.8.9.10.1.2.3.4.5.6 解决方案 用循环,对1--8的数据向后移,0,9号数据单独考虑 解决方案二: 百度上有个算法,你试试效率怎么样 void Reverse(int *arr, int b, int e) { for(; b < e; b++, e--) { int temp = arr[e]; arr[e] = arr[b]; arr[b]

超时-一道关于大数幂运算的题目,c语言实现

问题描述 一道关于大数幂运算的题目,c语言实现 题目描述 幂运算是常见的数学运算之一,其原理是用同一个数相乘多次,但是有的时候当幂指数特别大的时候,这样的运算就太浪费时间.请大家学会在幂中加特技,让幂运算的效率提高到可以接受的程度.输入: 第一个行一个整数T,表示有T组数据 每组数据,输入x,y 求x的y次幂 (2≤ x ,y≤10^9)输出: 每组数据输出一个整数,表示幂运算对1000000007取模后的结果样例输入: 2 2 4 2 100000000样例输出: 16 494499948 我

我真的不会-我是初学,一个关于顺序查找和折半查找的算法有错,求解答

问题描述 我是初学,一个关于顺序查找和折半查找的算法有错,求解答 ```#include #define Max 256 typedef struct Keylist { int key[Max]; int len; }Keylist; void creatKlist(Keylist L) { int i=0; printf("**建立静态表**n"); printf("你需要构建多少个数据,请输入:"); scanf("%d",&L.l

C语言求幂计算的高效解法_C 语言

本文实例演示了C语言求幂计算的高效解法.很有实用价值.分享给大家供大家参考.具体方法如下: 题目如下: 给定base,求base的幂exp 只考虑基本功能,不做任何边界条件的判定,可以得到如下代码: #include <iostream> using namespace std; int cacExp(int base, int exp) { int result = 1; int theBase = 1; while (exp) { if (exp & 0x01) result =