每个合数都可以写成几个质数相乘的形式,其中每个质数都是这个合数的质因数。如果一个质数是某个数的因数,那么就说这个质数是这个数的质因数。而这个因数一定是一个质数。
把一个合数用质因数相乘的形式表示出来,叫做分解质因数。如30=2×3×5 。分解质因数只针对合数。
质数: 质数(prime number)又称素数,有无限个。
质数定义为在大于1的自然数中,除了1和它本身以外不再有其他因数。
合数: 合数指自然数中除了能被1和本身整除外,还能被其他数(0除外)整除的数。与之相对的是质数,而1既不属于质数也不属于合数。最小的合数是4。其中,完全数与相亲数是以它为基础的。
定义
质因数(或质因子)在数论里是指能整除给定正整数的质数。两个没有共同质因子的正整数成为互质。因为1没有质因子,所以1与任何正整数(包括自身)都是质数。正整数的因数分解可将正整数表示为一连串的质因子相乘,质因子如重复可以质数表示。根据算数基本定理,任何正整数皆有独一无二的质因子分解式。只有一个质因子的正整数为质数。
把一个合数分解成若干个质因数的乘积的形式,即求质因数的过程叫做分解质因数。
分解质因数只针对合数。(分解质因数也称分解素因数)求一个数分解质因数,要从最小的质数除起,一直除到结果为质数为止。分解质因数的算式叫短除法,和除法的性质差不多,还可以用来求多个个数的公因式。
例子
- 1没有质因子
- 5只有1个质因子,5本身。(5是质数)
- 6的质因子是2和3(6=2*3)
- 2、4、8、16等只有一个质因子:2(2是质数, $math_inline$4=2^2$math_inline$ , $math_inline$8=2^3$math_inline$ ,如此类推)
- 10有两个质因子:2和5.(10=2*5)
就是一个数的约数,并且是质数,比如 $math_inline$8=2 * 2 * 2$math_inline$ ,2就是8的质因数。 $math_inline$12=2 * 2 * 3$math_inline$ ,2和3就是12的质因数。把一个式子以 $math_inline$12=2 * 2 * 3$math_inline$ 的形式表示,叫做分解质因数。 $math_inline$16=2 * 2 * 2 * 2$math_inline$ ,2就是16的质因数,把一个合数写成几个质数相乘的形式表示,这也是分解质因数。
分解质因数的方法是先用一个合数的最小质因数去除这个合数,得出的数若是一个质数,就写成这个合数相乘形式;若是一个合数就继续按照原来的方法,直至最后是一个质数。
分解质因数有两种方法表示,除了大家最长知道的“短除法”之外,还有一种方法就是“塔形分解法”。
分解质因数对解决一些自然数和乘积的问题有很大的帮助,同时又为最大公约数和最小公倍数做了重要铺垫。
计算方法
短除法
求一个数的分解质因数,要从最小的质数除起,一直除到结果为质数为止。分解质因数的算式叫短除法,和除法性质差不多,还可以用来求多个个数的公因式:
求最大公因数的一种方法,也可以用来求最小公倍数。
求几个数最大公因数的方法,开始时用观察比较的方法,即:先把每个数的因数找出来,然后再找出公因数,最后在公因数中找出最大公因数。
例如:求12与18的最大公因数。
- 12的因数有:1、2、3、4、6、12
- 18的因数有:1、2、3、6、9、18
- 12与18的公因数有:1、2、3、6
- 12与18的最大公因数是6
这两种方法对求两个以上数的最大公因数,特别是数目较大的数,显然是不方便的。于是又采用了给每个数分别分解质因数的方法。
- $math_inline$12=2 * 2 * 3$math_inline$
- $math_inline$18=2 * 3 * 3$math_inline$
12与18都可以分成几种形式不同的乘积,但分解质因数连乘积就只有以上一种,而且不能再分解了。所分出的质因数无疑都能整除原数,因此这些质因数也都是原数的约数。从分解的结果来看,12与18都有公约数2和3,而他们的乘积2*3=6,就是12与18的最大公约数。
采用分解质因数的方法,也就是采用短除的形式,只不过是分别短除,然后再找公约数和最大公约数。如果吧这两个数合在一起短除,则更容易找出公约数和最大公约数。
从短除中不难看出,12和18都有公约数2和3,他们的乘积2*3=6就是12与18的最大公约数。与前边分别分解质因数相比较,可以发现:不仅结果相同,而且短除法竖式左边就是这两个数的公共质因数,而两个数的最大公约数,就是这两个数的公共质因数的连乘积。
实际应用中,是吧需要计算的两个或多个数放置在一起,进行短除。
在计算多个数的最小公倍数时,对其中任意两个数存在的约数都要算出,其它无此约束的数则原样落下。最后把所有约数和最终剩下无法约分的数连乘即得到最小公倍数。
只含有一个质因数的数一定是亏数。(在数论中,若一个正整数除了本身之外所有因子之和比此数自身小,则称此数为亏数(又称作缺数)。)
短除法详解:
短除富豪就是除号倒过来。短除就是在除法中写余数的地方写两个数共有的质因数,然后落下两个数被共有质因数整除的商,之后再除,以此类推,直到结果互质为止(两个数互质)
而在用短除法计算多个数时,对其中任意两个数存在的因数都要算出,其它没有这个因数的数则原样落下。直到剩下每两个数都是互质关系。
求最大公因数遍乘一边,求最小公倍数遍乘一圈。
在用短除计算多个数时,对其中任意两个数存在的因数都要算出,其它没有这个因数的数则原样落下。直到剩下每两个都是互质关系。**求最大公约数遍乘左边所有数公共的因数,求最小公倍数遍乘一圈。**这种方法对求两个以上数的最大公因数,特别是数目较大的数,显然是不方便的。于是又采用了给每个数分别分解质因数的方法。
Pollard Rho因数分解
1975年,John M. Pollard提出了第二种因数分解的方法,Pollard Rho快速因数分解。该算法时间复杂度为 $math_inline$O(n^{(1/4)})$math_inline$ 。
将一个正整数分解质因数。例如:输入90,打印出 $math_inline$90=2 * 3 * 3 * 5$math_inline$ 。 程序分析:对n进行分解质因数,应先找到一个最小的质数k,然后按下述步骤完成:
- 如果这个质数恰好等于n,则说明分解质因数的过程已经结束,打印出即可。
- 如果n<>,但n能被k整除,则应打印出k的值,并用n除以k的商,作为新的正整数n,重复执行第一步。
- 如果n不能被k整除,则用k+1作为k的值,重复执行第一步。
//将一个数n分解为若干个从小到大排列的质数的积
void f1(int n) {
cout << n << " = ";
int n2 = n;
if (n < 2) {
cout << "ERROR" << endl;
} //小于2的数不合法,若n为质数则输出它本身
for (int i = 2; i * i <= n2; i++) { //根号n复杂度
while (n2 % i == 0) {
n2 = n2 / i;
cout << i;
if (n2 != 1) cout << "*";
}
}
if (n2 != 1) cout << n2; //当n为质数
cout << endl;
}
void f2(int n) {
cout << n << " = ";
for (int i = 2; i <= n; i++) {
while (n != i) {
if (n % i == 0) {
cout << i << '*';
n = n / i;
} else break;
}
}
cout << n << endl;
}
void f3(ll n) {
cout << n << '=';
int flag = 0;
for (ll i = 2; i * i <= n; i++) {
while (n % i == 0) {
n = n / i;
if (!flag) cout << i;
else cout << '*' << i;
flag |= 1;
}
}
if (n != 1 && !flag) cout << n << endl;
else if (n != 1 && flag) cout << '*' << n << endl;
else cout << endl;
}
另外代码:
我们用所有正整数试验一下,从2开始进行拭除,逐步增加除数的值,去寻找一个可以整除n的数。在Eratosthenes筛法的讨论中,我们知道如果n是一个复合数,那么它就会有一个素数 $math_inline$p\leq\sqrt{n}$math_inline$ 。
这个算法有两个循环路径,内部的和外部的。外部循环求唯一因数,内部循环求一个因数的多个复本。例如: $math_inline$24=2^3\times3$math_inline$ ,外部循环求出因数2和3.内部循环求出2是一个多因数。
void trial_divisio_fac(int n) {
int a = 2;
cout << n << "= ";
while (a * a <= n) {
while (n % a == 0) {
cout << a << '*';
n = n / a;
}
a++;
}
if (n > 1) cout << n;//n没有因数
cout << endl;
}
上面的代码解释比较清楚。为什么这种方法可以得到素数。
因为我们在内层循环中,已经把当前a的所有倍数都去除了。这跟埃斯托尼算法一样的。
如果整数较小,这种情况下拭除法通常都是很有效的,但是如果用来分解更大的整数,拭除法就变得非常低效甚至不可用了。这种算法的复杂度是随着n的增加呈指数级别增长的。
拭除法是整数分解算法中最简单和最容易理解的算法。
给定一个合数n(这里,n是待分解的整数),拭除法看成是用小于等于 $math_inline$\sqrt{n}$math_inline$ 的每个素数去拭除待分解的整数。如果找到一个数能够整除除尽,这个数就是待分解整数的因子。
运用拭除法求1233的因数
$math_inline$1233=3^2 * 137$math_inline$