因为我们将处理一些大整数,所以需要调整一下如何看待输人规模和基本算术运算的代价的看法。
在本章中,一个“大的输入”意味着输入包含“大的整数”,而不是输人中包含“许多整数”。因此,我们将根据输入数的位数来衡最输人的规模,而不是仅根据输人中包含的整数的个数。在本章中,我们在分析算法时一般既考虑算术运算的次数,也考虑它们所要求的位操作的次数。
一:初等数论概念
一个整数能被另一个整数整除的概念是数论中的一个中心概念。记号d|a,读作“d整除a”,意味着对某个整数k,有a=kd。比如3整除6,则6=2*3(3是除数,6是被除数)。0可被任何整数整除。
如果a>0且d|a,则|d|<=|a|。
如果d|a并且d>=0,则d是a的约数,a是d的倍数。d|a当且仅当(-d)|a,因此一般定义约数为非负整数。一个整数a的约数最小为1,最大为|a|。每个整数a都可以被其平凡约数1和a整除,a的非平凡约数也成为a的因子,比如20的因子有2,4,5和10.
对于某个整数a>1,如果它仅有平凡约数1和a,则称a为素数(质数)。如果a>1且a不是素数,则a为合数。1不是素数,也不是合数,同样,0和所有非负数既不是素数,也不是合数。
已知一个整数n,所有整数都可以根据它们除以n所得的余数来进行分类,数论的大部分理论都是基于上述划分的。
对任意整数a和任意正整数n,存在唯一的整数q和r,满足0<=r<n,并且a=qn+r。q为商,r=a mod n称为余数。n|a当且仅当a mod n = 0.
根据整数模n所得的余数,可以把整数分成n个等价类。记为, = {a+kn:k ∈ Z},是一个集合,其中包含了模n的余数为a的所有整数。比如: = {..., -11,-4, 3, 10, 17, ...}。
如果d是a的约数,且d也是b的约数,则d是a和b的公约数。1是任意两个整数的公约数,公约数有一条重要性质:d|a并且d|b,则d|(a+b),d|(a-b)。或者更一般的,对于任意整数x和y,有d|a并且d|b,则d|(ax+by)。
a|b且b|a,则a=b或者a=-b。
a和b的最大公约数表示为gcd(a,b).比如gcd(24, 30) = 6.
gcd(a, b)是一个在1和min(|a|, |b|)之间的整数。定义gcd(0, 0) = 0,gcd有下列性质:
如果a和b是不都为0的任意整数,则gcd(a, b)是a与b的线性组合集合{ax+by: x,y ∈ Z }中的最小正元素。(证明见附注)
对于任意整数a和b,如果d|a,d|b,则d|gcd(a, b)。
对所有整数a和b,以及任意非负整数n,gcd(an, bn) = n gcd(a, b)。
对于所有正整数n, a和b,如果n|ab并且gcd(a, n) = 1,则n|b。
如果gcd(a, b) = 1,则a与b成为互质数。
对于任意整数a,b和p,如果gcd(a, p) = 1,且gcd(b, p)=1,则gcd(ab, p) = 1.
对所有素数p和所有整数a,b,如果p|ab, 则p|a或p|b(或两者都成立)。
合数a仅能以一种方式,写成如下的乘积形式:,其中为素数,且 < < ... < . 为正整数。
二:最大公约数
欧几里得算法是高效计算两个整数的最大公约数的算法,我们仅对非负整数进行讨论,因为gcd(a, b) = gcd(|a|, |b|)。
欧几里得算法的正确性由下面的性质得出:对于任意非负整数a和任意正整数b,gcd(a, b) = gcd(b, a mod b)。
证明:要证明gcd(a, b) = gcd(b, a mod b),可以证明gcd(a, b)| gcd(b, a mod b),以及gcd(b, a mod b)| gcd(a, b)。
假设gcd(a, b) = d,所以d|a, d|b,因a mod b = a – qb,所以d|a mod b,所以d|gcd(b, a mod b)。因而的证gcd(a, b)| gcd(b, a mod b)。反之即可的证gcd(b, a mod b)| gcd(a, b),所以gcd(a, b) = gcd(b, a mod b)。
算法描述如下:
EUCLID(a, b)
if b==0
return a
else return EUCLID(b, a mod b)
比如:EUCLID(30,21) = EUCLID(21,9) = EUCLID(9,3) = EUCLID(3,0) =3。一般情况下要求a>b,即使a <b,则EUCLID(a,b) = EUCLID(b, a mod b) =EUCLID(b, a)。
EUCLID执行中递归调用的次数为O(lg b)。
根据EUCLID算法,还可以得到其他类似的算法,比如求满足下列条件的系数x和y:d = gcd(a, b) = ax+by,可以有下列算法:
EXTENDED-EUCLID(a, b)
if b == 0
return (a, 1, 0)
else
(d’, x’, y’) = EXTENDED-EUCLID(b, a mod b)
(d, x, y) = (d’, y’, x’-(a/b)y’)
return (d, x, y)
三:素数判断
解决素数测试问题的一种简便方法是试除。试着用每个整数2,3,...,分别取整数n(大于2的整数可以跳过)。n是素数当且仅当没有一个试除整数能整除n。
比如对于数M,如果它存在两个因数,乘积等于M,这两个因数一定一个小于根号M,一个大于根号M。
因为M = *。如果两个数都在根号M以下,乘起来小于M,如果两个数都在根号M以上,乘起来一定大于M,所以两个数分布于根号M两边,那么我们只要找到其中一半有没有这样一个整数就可以了。如果有,自然对应的另一半也有一个和它对应的数,使它们的乘积为M。综上,对于以上的遍历求法,只需遍历到根号M即可。
附注:
证明:如果a和b是不都为0的任意整数,则gcd(a, b)是a与b的线性组合集合{ax+by: x,y Z }中的最小正元素。
该问题的证明属于贝祖定理的一部分:
http://zh.wikipedia.org/zh/%E8%B2%9D%E7%A5%96%E7%AD%89%E5%BC%8F,证明如下:
集合A={ax+by: x,y∈ Z },假设为其中的最小正元素: = a + b,设ax+by为集合A中的任意元素,根据“对任意整数a和任意正整数n,存在唯一的整数q和r,满足0<=r<n,并且a=qn+r”,所以,存在唯一的整数q和r,满足ax+by = q + r,其中0<=r<。
也就是:ax+by = q(a + b) + r,所以r=a(x-q) + b(y-q),所以r也属于集合A,又因为0<=r<,且为集合A中最小正元素,所以r=0。所以,|ax+by。特别的:|a;|b。所以,是a和b的公约数。
假设d=gcd(a,b)为a和b的最大公约数,因为 = a + b,所以d|。
因此, 是a和b的最大公约数,得证。