质因数分解和算术基本定理
因数是约数的另一个名称,一个数的因数中,是质数的那些就叫做该数的质因数。这个概念一般对于合数来说意义更大(质数只有1和自身两个因数,没太大必要分解)
对于一个合数来说,一个简单粗暴的分解质因数(Prime Factorization)方法,就是在所有因数中升序找出质数,然后把它们除尽。找质因数这件事,就要牵扯到算术基本定理了,其表达式如下:
N=n∏i=1(paii)=pa11∗pa22∗…∗pann
其中pi是比N小的质数,ai是其对应的幂。用自然语言描述就是,任何合数都可以表示为若干质数幂的乘积,这些质数全都比该数小。由此,可以继续得出以下4条推论:
1. 合数N某因数f的质因数,同样也是N的质因数
2. 对于推论1中的f,如果它是合数,那么f同样可以表示为若干N的质因数幂的乘积,且这些质因数全都小于f(理由就是推论1,f的质因数全都是N的质因数,且合数的质因数不可能包含自身)
3. 一个合数的因数,去掉1和自身,按照升序排列时,一定存在某最大的正整数L,使得因数序列长度为L的前缀中,每一个数都是质数(由上述两条推论得出,另一种说法就是该序列中合数一定不会出现在序列头端)
4. 在N的所有质因数中,如果存在大于√N的质因数p,那么该项在算术基本定理的表达式中,对应的指数必然是1(由y=√x在正整数集合上的单调增加性质得出,p的指数不小于2时,必然会比N大)
下面是对上述几个推论的一些说明:
以及对于算法实现,最重要的一条事实:如果按照升序枚举每个因数并将其除尽,能被选中的只有质因数。比如上面的156(22∗31∗131),除尽2和3之后,留下的应该是20∗30∗131,如果要继续选择4去除尽,和在剩下的部分中再除尽两个2是一回事,显然这是不可能的,对于6,12同理,只有最后剩下的质数13能被选中并除尽
C++ 代码
/**
* @brief 分解质因数
* @param 待分解的数
* 不仅要得出质因数有哪些,还要得出它们对应的指数
*/
void primeFactorization(int x) {
for (int i = 2; i <= x / i; i++) { //跟质数判断一样试除每个整数
int pw = 0;
while(x % i == 0) { //将该数除尽,有几次方就除几个
x /= i;
pw++;
}
if (pw > 0) { //只有当指数大于0时才有意义
cout << i << " " << pw << endl;
}
}
if (x > 1) { //如果还剩下,那么就代表这是那个大于sqrt(x)的
cout << x << " 1" << endl;
}
}