大數的質因數分解一直以來是亟需解決的難題。本文從最基本的試除法開始,**分解質因數的方法。
下面的程式在開頭定義了乙個巨集opt,如果刪掉這個定義,就可以執行最原始的演算法。
一、樸素演算法
#include #include #include using namespace std;
#define opt
int main()
else
}printf("%d\n",n);
#endif // opt
#ifdef opt
//6n+1 6n+5
//deal with number <=5 first
for (int i=2;i<=5;)
else
++i;
}for (int k=1;(6*k+5)<=sqrt(n);)
while (n%(6*k+5)==0)
++k;
}if (n!=1)
printf("%d\n",n);
else
printf("\n");
#endif // opt
}return 0;
}
在上段**中,核心**為:
for (int i=2;i<=sqrt(n);)
else
}printf("%d\n",n);
i為進行嘗試的質因子,這裡並不需要判斷i是否為質數,因為i若是合數,並且滿足n%i==0,那麼i的質因子在i的前面肯定出現過,其質因子一定已經作為n的質因子除過了,所以也就不會再出現這樣乙個合數i
以100=2*2*5*5為例,不必要擔心4也是100的約數而被誤作為質因子。因為100在連續兩次除以2後等於25,25是沒有4這個因子的。
還有一點需要注意的是最後一行:
printf("%d\n",n);
不能刪去,根據我們的程式,演算法結束時的n剛好是最後乙個質因子。
二、優化嘗試(一)
以上**的時間複雜度為o( sqrt(n) ),在尋找較大的質因子時,需要以1為步長加上去,這還是比較消耗時間的。
考慮這樣的乙個數列6n, 6n+1, 6n+2, 6n+3, 6n+4, 6n+5, 其中6n, 6n+2, 6n+3, 6n+4, 都明顯地有2, 3等約數,不可能是約數。只有形如6n+1,6n+5的數,才有可能有約數。利用這種思路,我認為可以做到乙個常數上的小優化。在開頭給出的程式中,巨集opt指明的程式段就是用這種思想編寫的。
但是實際測試並非如此,實際測試中,對1萬到11萬的數進行分解,樸素演算法是22.033秒,而所謂的優化演算法時間為41.645s,幾乎慢了一倍。
可能的原因是我的「優化」寫得太複雜了吧。讓我進一步挖掘一下。
分解質因數
質因數概念 每個合數都可以寫成幾個質數相乘的形式,這幾個質數就都叫做這個合數的質因數。如果乙個質數是某個數的因數,那麼就說這個質數是這個數的質因數。而這個因數一定是乙個質數。演算法原理 先根據需要分解的合數生成乙個質數表。然後依次從小到大依次除合數,每次除之後都將儲存步驟。表達不好,還是看 吧 us...
分解質因數
分解質因數 問題描述 求出區間 a,b 中所有整數的質因數分解。輸入格式 輸入兩個整數a,b。輸出格式 每行輸出乙個數的分解,形如k a1 a2 a3.a1 a2 a3.k也是從小到大的 具體可看樣例 樣例輸入 3 10 樣例輸出 3 34 2 2 5 56 2 3 7 78 2 2 2 9 3 3...
分解質因數
題目內容 每個非素數 合數 都可以寫成幾個素數 也可稱為質數 相乘的形式,這幾個素數就都叫做這個合數的質因數。比如,6可以被分解為2x3,而24可以被分解為2x2x2x3。現在,你的程式要讀入乙個 2,100000 範圍內的整數,然後輸出它的質因數分解式 當讀到的就是素數時,輸出它本身。輸入格式 乙...