目录
求最大公约数方法
质因数分解法
把每个数分别分解质因数,再把各数中的全部公有质因数提取出来连乘,所得的积就是这几个数的最大公约数。
例子
189和180两数的质因数分解法。
189=3*3*3*7
180=3*3*2*5
则取两个共有的3,即最大公约数为9。
JS实现
//判断是否是质数
function isPrime(x) {
if (x <= 3) {
return true
} else {
for (let i = 2; i <= Math.sqrt(x); i++) {
if (x % i == 0) {
return false
}
}
}
return true
}
//分解质因数,因数存在返回数组
function decomposedPrimeFactor(x) {
let primeFactor = []
if (isPrime(x)) {
return [x]
} else {
for (let i = 2; i <= Math.sqrt(x); i++) {
if (x % i == 0 && isPrime(i)) {
primeFactor.push(i, ...decomposedPrimeFactor(x / i))
return primeFactor
}
}
}
return primeFactor
}
//求最大公约数
function GCD(x, y) {
let arrX = decomposedPrimeFactor(x)
let arrY = decomposedPrimeFactor(y)
//求两数组共有的值
let arr = arrX.filter(v => arrY.includes(v))
let sum = 1
//数组去重
arr = [...new Set(arr)]
for (let i = 0; i < arr.length; i++) {
sum = sum * arr[i] ** (Math.min(arrX.filter((v) => v == arr[i]).length, arrY.filter((v) => v == arr[i]).length))
}
return sum
}
短除法
用这几个数的公约数连续去除,一直除到所有的商互质为止(这个步骤相当于质因数分解后求共有的因数有哪些),然后把所有的除数连乘起来,所得的积就是这几个数的最大公约数。
辗转相除法
用大的数除以小的数,如果余数不为0,就在用除数除以余数,反复进行,知道余数为0,取此时的除数即为最大公约数。
定理
两个整数的最大公约数等于其中较小的那个数和两数相除余数的最大公约数。
gcd(a,b) = gcd(b,a mod b) (不妨设a>b 且r=a mod b ,r不为0)
证明
a可以表示成a = kb + r(a,b,k,r皆为正整数,且r
假设d是a,b的一个公约数,记作d|a,d|b,即a和b都可以被d整除。
而r = a - kb,两边同时除以d,r/d=a/d-kb/d,由等式右边可知m=r/d为整数,因此d|r
因此d也是b,a mod b的公约数。
因(a,b)和(b,a mod b)的公约数相等,则其最大公约数也相等,得证。
例子
假如需要求 1997 和 615 两个正整数的最大公约数,用欧几里得算法,是这样进行的:
1997 / 615 = 3 (余 152)
615 / 152 = 4(余7)
152 / 7 = 21(余5)
7 / 5 = 1 (余2)
5 / 2 = 2 (余1)
2 / 1 = 2 (余0)
至此,最大公约数为1
以除数和余数反复做除法运算,当余数为 0 时,取当前算式除数为最大公约数,所以就得出了 1997 和 615 的最大公约数
JS实现
function GCD(x,y){
if(x>=y&&x%y==0){
return y
}else{
return GCD(y,x%y)
}
}
更相减损法
用大的数减小的数,如果结果不等于减数,则再用减数减结果,反复进行,知直到结果等于减数,此时减数即为两数的最大公约数。
定理
两个整数的最大公约数等于其中较小的那个数和两数相减的最大公约数。
例子
求98与63的最大公约数。
解:由于63不是偶数,把98和63以大数减小数,并辗转相减:
98-63=35
63-35=28
35-28=7
28-7=21
21-7=14
14-7=7
所以,98和63的最大公约数等于7。
JS实现
function GCD(x, y) {
if (x >= y) {
if (x - y == y) {
return y
} else {
return GCD(y, x - y)
}
} else {
if (y - x == x) {
return x
} else {
return GCD(y, y - x)
}
}
}
练习题目
题目描述
从n个不同元素中,任取m(m<=n)个元素并组成一组,叫做从n个元素中取出m个元素的一个组合;则像这样取出所有组合的组合个数,叫做从n个元素中取出m个元素的组合数,用符号c(n,m)表示。
计算公式为:C(n,m)=n!/((n-m)!*m!)
现在你的任务是求出C(2n,1),C(2n,3),C(2n,5),...,C(2n,2n-1)的最大公约数。
输入:
一个整数(1<n<=10000)
输出:
C(2n,1),C(2n,3),C(2n,5),...,C(2n,2n-1)的最大公约数
样例:
输入样例1: 3
输出样例1: 2
提示:
范例中n=3,则C(2n,1),C(2n,3),C(2n,5),...,C(2n,2n-1)为6,20,6,则他们的最大公约数为2
解析
C(2n,1)+C(2n,3)+C(2n,5)+...+C(2n,2n-1)=C(2n,2)+C(2n,4)+C(2n,6)+...+C(2n,2n)=2**(n-1)
由更相减损法中的定理a和b(a>b,a-b=c)的最大公约数相当于c和a的公约数,可以推出b、c的最大公约数相当于b+c和c的最大公约数一样。
那么C(2n,1),C(2n,3)的最大公约数和C(2n,1)、C(2n,1)+C(2n,3)的最大公约数相同。
C(2n,1),C(2n,3),C(2n,5)的最大公约数和C(2n,1),C(2n,1)+C(2n,3)+C(2n,5)的最大公约数相同,以此类推:
C(2n,1),C(2n,3),C(2n,5),...,C(2n,2n-1)的最大公约数即和C(2n,1),C(2n,1)+C(2n,3)+C(2n,5)+...+C(2n,2n-1)相同
也就是求2**(n-1)和C(2n,1)=2n的最大公约数。
2**(n-1)的质因数分解都为2,所以只用看2n能分解出多少个2。
number&-number:正整数number和自身的相反数求按位与的结果,number最大能被2**n整除(n>=0)。
答案
console.log(2*(n&-n))