給出乙個整數n,先找到最小質數k,然後按照下面步驟完成:
(1)如果這個質數恰等於(小於的時候,繼續執行迴圈)n,則說明分解質因數的過程已經結束,另外 列印出即可。
(2)但n能被k整除,則應列印出k的值,並用n除以k的商,作為新的正整數n.
重複執行第二步。
(3)如果n不能被k整除,則用k+1作為k的值,重複執行第一步。
#include int main() else
} }printf("\n");
return 0;
}
如果輸入的資料是偶數的話,迴圈從2開始,執行while迴圈後這個數肯定程式設計奇數。那麼大家從小學學數學的時候都知道,質數除去2之外,都是奇數。自然數序列中奇數有兩種,一種是質數(奇數),另一種肯定是質奇數的倍數。所當輸入的偶資料程式設計奇數之後肯定能被分解,分解或是乙個質奇數,或者是幾個質奇數的乘積。如果輸入資料時奇數的話,那很顯然能被分解成質奇數的乘積。此程式是當num=1的時候結束。
可以很清楚的看到,上面的演算法有很多不必要的判斷,就是當i = 4,或者 i = 6的時候。所以下面給出乙個更高效的演算法。
1,首先判斷n是否可以被2整除,如果可以,那麼n/2之後再進行判斷,直至n變成奇數。
2,接下來開始乙個從i=3,到 i = sqrt(n)的迴圈,當i可以整除n的時候,進行整除運算,直至不能整除位置,然後i一次遞增2。
3,當第2部結束之後得到的n,要對其進行判斷,看它是1還是比2大的質數。
#include#includevoid prime_factors(int n)
for(i = 3; i <= sqrt(n); i += 2)
} if(n > 2)
printf("\n");
}void main()
第1,2步處理的是當n是組合數的情況(就是非質數),第3步是處理n是質數的情況。為了證明整個演算法的正確性,需要證明1,2的確是處理了組合數的情況。可以清晰的看到1處理了所有偶數的情況,第一步之後得到的n肯定是個奇數,而且n的兩個不同的質數因子之間的差值至少為2。因為n的值是隨著程式不斷變動的,所以假設n的最初值記錄在k中。上面的演算法第二步中的for迴圈沒有執行到k的平方根的時候就結束了。這是一種很巧妙的優化。下面證明這個優化的正確性:對於每個組合數而言,最少有乙個素數因子是小於或者等於它的平方根的,用反證法證明這一點。假設a,b是n的兩個因子,a * b = n, 假如a,b都大於n的平方根,那麼a*b的值就會大於n,與他們之積等於n相反。在第2步的迴圈中,主要做以下的工作:a,找到n的最小素數因子;b,在while迴圈中,通過不斷的n/i,來去除n中包含的所有i因子;c,通過重複的執行a,b兩步,使得最終的n要麼是1,要麼是比2大的素數。
C語言判斷素數(兩種方法)
素數又稱質數,是指除了1和它本身外,不能被其他任何整數整除的數,例如17就是素數,因為它不能被2 16任意整數整除。思路1 判斷乙個數是否為素數,只需把m被2 m 1之間的每乙個整數去除,如果都不能被整除,那麼m就是乙個素數。思路2 另外判斷方法可以簡化,m只需被2 m之間的每乙個整數去除就可以了,...
LCA兩種方法
lca least common ancestors 即最近公共祖先,是指在有根樹中,找出某兩個結點u和v最近的公共祖先。模板題 anc i j 表示第i個點的2 j的祖先的標號 整個過程就是兩個點往上跳到同一深度,再一起往上跳找到lca include include using namespac...
post get 兩種方法
a.定義乙個get函式 get url,headers none defget url,headers none return urlrequests url,headers headers 內部可以呼叫urlrequests 如果不寫headers headers會被預設為none b.定義乙個p...