素數的各種篩法 C實現

2021-10-22 16:53:21 字數 1531 閱讀 2404

#include

#include

intisprime

(int n)

}return1;

}

原理同2

#include

#include

#define max_n 100

int prime[max_n +5]

=;void

init()

}}intmain()

return0;

}

描述:

要得到自然數n以內的全部素數,必須把不大於的所有素數的倍數剔除,剩下的就是素數。

給出要篩數值的範圍n,找出以內的素數。先用2去篩,即把2留下,把2的倍數剔除掉;再用下乙個質數,也就是3篩,把3留下,把3的倍數剔除掉;接下去用下乙個質數5篩,把5留下,把5的倍數剔除掉;不斷重複下去…。

#include

#include

#define max_n 100

int prime[max_n +5]

=;void

init()

}return;}

intmain()

return0;

}

時間複雜度o(n),空間複雜度o(n)

如果用遍歷取餘,那麼每判定乙個數都要從頭開始再遍歷一遍,而線性篩法只在開始一次性運算完,以後只要查表即可,查表通常只需要1條語句。所以如果你的程式從始至終只需要判定那麼幾次素數那麼用遍歷取餘即可,但是如果需要多次判定素數,而且這個數還不是很小的話,那麼線性篩法就會體現出巨大的優越性來。

線性篩法的核心原理: 每個合數必有乙個最大因子m(不包括它本身),用這個因子把合數n篩掉。還有另一種說法,每個合數必有乙個最小素因子p,用這個因子p*m篩掉合數n。

證明:合數的因子一定多於2個,既然是幾個數,就一定有最大的乙個,並且最大因子是唯一的,所以合數只會被它自己唯一的最大因子篩掉一次(這裡利用最大因子和最小素因子相乘進行只篩掉1次即可把時間複雜度降低為o(n)),把所有合數篩掉後剩下的就全是素數了。

篩掉n的條件:

1、n = p * m,且p為n中最小的素因子,m是n中最大的因子

2、p一定小於等於m的最小素因子

3、利用m * p(此處p是所有不大於m的最小素因子的集合,如若m=45,p可取2,3進行標記90和135)

如果想看線性篩的嚴格證明請看數論中的證明。

對於每乙個數m,乘上小於等於m的最小素因數的素數集p,就得到以m為最大因數的合數集n。設有乙個數m,只要將所有以比m小的數為最大因數的合數篩去,那麼比最大合數n小的數里剩下的就只有素數了。這就是線性篩法求素數的方法。

#include

#include

#define max_n 100

int prime[max_n +5]

=;void

init()

}return;}

intmain()

return0;

}

後續更新

素數篩法(素數篩 線性篩)

求素數的方法在現階段可以總結為三種 這種方法最為簡單但效率太低,經過優化時間複雜度最低是o n sqrt n 輸入乙個n,輸出n以內所有素數 include intprime int n if flag 0 優化 printf d i intmain 素數篩法原理 2是素數,那麼2的所有倍數都是合數...

C語言素數篩法

埃氏篩法 樸素篩法及其優化 與尤拉篩 線性篩法 略解 2018.08.09 oi學習oi演算法數論 在之前我們學過的最樸素的篩法就是埃氏篩法 埃拉託斯特尼篩法 它的複雜度是 theta n log 2 n nlog2 n 其實這個樸素的篩法可以進行常數上的優化。還有一種更炫酷的篩法 尤拉篩,即線性篩...

素數的篩法

素數的篩法有很多種 在此給出常見的三種方法 以下給出的所有 均已通過這裡的測試 名字好長 joy 不過 很短 思路非常簡單,對於每乙個素數,列舉它的倍數,它的倍數一定不是素數 這樣一定可以保證每個素數都會被篩出來 還有,我們第一層迴圈列舉到 sqrt n 就好,因為如果當前列舉的數大於n,那麼它能篩...