日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > java >内容正文

java

自然数 素数 质数_在Java中获取素数的无限列表

發(fā)布時間:2023/12/3 java 43 豆豆
生活随笔 收集整理的這篇文章主要介紹了 自然数 素数 质数_在Java中获取素数的无限列表 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

自然數(shù) 素數(shù) 質(zhì)數(shù)

一個常見的問題是確定數(shù)字的素因式分解。 蠻力方法是審判部門( 維基百科 , 可汗學(xué)院 ),但是如果必須考慮多個數(shù)字,這需要大量的浪費工作。

一種廣泛使用的解決方案是Eratosthenes篩( 維基百科 , 數(shù)學(xué)世界 )。 容易修改Eratosthenes的篩網(wǎng)以使其包含每個復(fù)合數(shù)的最大素數(shù)。 這使得隨后計算數(shù)字的素因式分解非常便宜。

如果我們只關(guān)心素數(shù),則可以使用帶有Eratosthenes篩子的位圖,也可以使用Atkin篩子( )。

(旁注:為清楚起見,我忽略了素數(shù)始終為“ 1 mod 2,n> 2”和“ 1或5 mod 6,n> 5”這一事實所引起的常見優(yōu)化。這可以大大減少篩子所需的內(nèi)存量。)

public enum SieveOfEratosthenes {SIEVE;private int[] sieve;private SieveOfEratosthenes() {// initialize with first million primes - 15485865// initialize with first 10k primes - 104729sieve = initialize(104729);}/*** Initialize the sieve.*/private int[] initialize(int sieveSize) {long sqrt = Math.round(Math.ceil(Math.sqrt(sieveSize)));long actualSieveSize = (int) (sqrt * sqrt);// data is initialized to zeroint[] sieve = new int[actualSieveSize];for (int x = 2; x < sqrt; x++) {if (sieve[x] == 0) {for (int y = 2 * x; y < actualSieveSize; y += x) {sieve[y] = x;}}}return sieve;}/*** Is this a prime number?** @FIXME handle n >= sieve.length!* * @param n* @return true if prime* @throws IllegalArgumentException* if negative number*/public boolean isPrime(int n) {if (n < 0) {throw new IllegalArgumentException("value must be non-zero");}boolean isPrime = sieve[n] == 0;return isPrime;}/*** Factorize a number** @FIXME handle n >= sieve.length!* * @param n* @return map of prime divisors (key) and exponent(value)* @throws IllegalArgumentException* if negative number*/private Map<Integer, Integer> factorize(int n) {if (n < 0) {throw new IllegalArgumentException("value must be non-zero");}final Map<Integer, Integer> factors = new TreeMap<Integer, Integer>();for (int factor = sieve[n]; factor > 0; factor = sieve[n]) {if (factors.containsKey(factor)) {factors.put(factor, 1 + factors.get(factor));} else {factors.put(factor, 1);}n /= factor;}// must add final termif (factors.containsKey(n)) {factors.put(n, 1 + factors.get(n));} else {factors.put(n, 1);}return factors;}/*** Convert a factorization to a human-friendly string. The format is a* comma-delimited list where each element is either a prime number p (as* "p"), or the nth power of a prime number as "p^n".* * @param factors* factorization* @return string representation of factorization.* @throws IllegalArgumentException* if negative number*/public String toString(Map factors) {StringBuilder sb = new StringBuilder(20);for (Map.Entry entry : factors.entrySet()) {sb.append(", ");if (entry.getValue() == 1) {sb.append(String.valueOf(entry.getKey()));} else {sb.append(String.valueOf(entry.getKey()));sb.append("^");sb.append(String.valueOf(entry.getValue()));}}return sb.substring(2);} }

該代碼有一個主要弱點-如果請求的數(shù)字超出范圍,它將失敗。 有一個簡單的解決方法–我們可以根據(jù)需要動態(tài)調(diào)整篩子的大小。 我們使用Lock來確保多線程調(diào)用不會使篩選器處于中間狀態(tài)。 我們需要注意避免在讀鎖和寫鎖之間陷入僵局。

private final ReadWriteLock lock = new ReentrantReadWriteLock();/*** Initialize the sieve. This method is called when it is necessary to grow* the sieve.*/private void reinitialize(int n) {try {lock.writeLock().lock();// allocate 50% more than required to minimize thrashing.initialize((3 * n) / 2);} finally {lock.writeLock().unlock();}}/*** Is this a prime number?* * @param n* @return true if prime* @throws IllegalArgumentException* if negative number*/public boolean isPrime(int n) {if (n < 0) {throw new IllegalArgumentException("value must be non-zero");}if (n > sieve.length) {reinitialize(n);}boolean isPrime = false;try {lock.readLock().lock();isPrime = sieve[n] == 0;} finally {lock.readLock().unlock();}return isPrime;}/*** Factorize a number* * @param n* @return map of prime divisors (key) and exponent(value)* @throws IllegalArgumentException* if negative number*/private Map<Integer, Integer> factorize(int n) {if (n < 0) {throw new IllegalArgumentException("value must be non-zero");}final Map<Integer, Integer> factors = new TreeMap<Integer, Integer>();try {if (n > sieve.length) {reinitialize(n);}lock.readLock().lock();for (int factor = sieve[n]; factor > 0; factor = sieve[n]) {if (factors.containsKey(factor)) {factors.put(factor, 1 + factors.get(factor));} else {factors.put(factor, 1);}n /= factor;}} finally {lock.readLock().unlock();}// must add final termif (factors.containsKey(n)) {factors.put(n, 1 + factors.get(n));} else {factors.put(n, 1);}return factors;}

Iterable <Integer>和foreach循環(huán)

在現(xiàn)實世界中,使用foreach循環(huán)(或顯式Iterator)通常比逐項探查表要容易得多。 幸運的是,創(chuàng)建一個迭代器很容易,該迭代器建立在我們的自增長篩子上。

/*** @see java.util.List#get(int)** We can use a cache of the first few (1000? 10,000?) primes* for improved performance.** @param n* @return nth prime (starting with 2)* @throws IllegalArgumentException* if negative number*/public Integer get(int n) {if (n < 0) {throw new IllegalArgumentException("value must be non-zero");}Iterator<Integer> iter = iterator();for (int i = 0; i < n; i++) {iter.next();}return iter.next();}/*** @see java.util.List#indexOf(java.lang.Object)*/public int indexOf(Integer n) {if (!isPrime(n)) {return -1;}int index = 0;for (int i : sieve) {if (i == n) {return index;}index++;}return -1;}/*** @see java.lang.Iterable#iterator()*/public Iterator<Integer> iterator() {return new EratosthenesListIterator();}public ListIterator<Integer> listIterator() {return new EratosthenesListIterator();}/*** List iterator.** @author Bear Giles <bgiles@coyotesong.com>*/static class EratosthenesListIterator extends AbstractListIterator<Integer> {int offset = 2;/*** @see com.invariantproperties.projecteuler.AbstractListIterator#getNext()*/@Overrideprotected Integer getNext() {while (true) {offset++;if (SIEVE.isPrime(offset)) {return offset;}}// we'll always find a value since we dynamically resize the sieve.}/*** @see com.invariantproperties.projecteuler.AbstractListIterator#getPrevious()*/@Overrideprotected Integer getPrevious() {while (offset > 0) {offset--;if (SIEVE.isPrime(offset)) {return offset;}}// we only get here if something went horribly wrongthrow new NoSuchElementException();}} }

重要提示:代碼:

for (int prime : SieveOfEratosthenes.SIEVE) { ... }

本質(zhì)上是一個無限循環(huán)。 僅當(dāng)JVM在分配新的篩選器時耗盡堆空間時,它才會停止。

實際上,這意味著我們可以在篩子中保持的最大質(zhì)數(shù)約為1 GB。 這需要4 GB和4字節(jié)的整數(shù)。 如果我們只關(guān)心素數(shù)并使用常見的優(yōu)化,則4 GB可以保存有關(guān)64 GB值的信息。 為簡單起見,我們可以將其稱為9到10位數(shù)字(以10為基數(shù))。

如果將篩子放在磁盤上怎么辦?

沒有理由將篩子保留在內(nèi)存中。 我們的迭代器可以從磁盤而不是內(nèi)存緩存中安靜地加載值。 一個4 TB的磁盤(可能是在原始模式下訪問的)似乎將我們的篩子的大小提高到14到15位數(shù)字(以10為基數(shù))。 實際上,它會少一些,因為我們必須將原始類型的大小從int到long增大一倍,然后再擴大到更大的格式。

更多!

通過注意我們只需要計算sqrt(n)即可初始化n個值的篩子,從而可以大大增加篩子的有效尺寸。 我們可以反過來說,可以使用完全填充的n個值的篩子填充另一個n 2個值的篩子。 在這種情況下,我們只想填充一個波段,而不是整個n 2篩。 現(xiàn)在,我們的內(nèi)存中篩子可以覆蓋最多約40位數(shù)字的數(shù)字(以10為基數(shù)),基于磁盤的篩子可以跳到多達60位數(shù)字的數(shù)字(以10為基數(shù)),減去較大值所需的空間。

沒有理由不能進一步采用這種方法–使用小篩子來引導(dǎo)較大的瞬態(tài)篩子,然后依次使用它來填充更大的篩子。

但是這需要多長時間?

是的,有摩擦。 初始化n個值的篩網(wǎng)的成本為O(n 2 ) 。 您可以使用各種調(diào)整來減少常數(shù),但是到了一天結(jié)束時,您將訪問每個節(jié)點一次( O(n) ),然后在每個這些點之外訪問一些與n成正比的滾動值。 值得一提的是,保留CPU的緩存體系結(jié)構(gòu)可能會產(chǎn)生很大的不同。

實際上,任何最新的系統(tǒng)都應(yīng)能夠在幾秒鐘內(nèi)創(chuàng)建一個包含前百萬個素數(shù)的篩子。 將篩子激增到最初的十億個素數(shù),如果JVM堆空間有限迫使我們大量使用磁盤,時間可能跳到一周,甚至一個月。 我的直覺是,填充TB磁盤需要花費數(shù)月甚至數(shù)年的服務(wù)器場時間

何必呢 ?

對于我們大多數(shù)人來說,主要收獲是如何用小種子(例如n = 1000的篩子)開始收集并根據(jù)需要透明地進行生長的演示。 對于素數(shù),這很容易,但是想像一下RSS提要使用相同的方法并不是一件容易的事。 我們習(xí)慣于將Iterators視為Collections的一些乏味方面,但實際上,將它們用作Iterable的一部分時,它們?yōu)槲覀兲峁┝撕芏囔`活性。

大型篩分也是一個實際原因-分解大量。 有幾種很好的算法可以分解大量數(shù)據(jù),但是它們很昂貴-即使在服務(wù)器場中,即使是“少量”數(shù)據(jù)也可能需要數(shù)月或數(shù)年。 這就是為什么第一步始終要使用“小”素數(shù)進行試驗劃分的原因-這可能需要一天的時間。

源代碼

好消息是我已經(jīng)為此發(fā)布了源代碼……壞消息是當(dāng)我處理Project Euler問題時,這是正在進行的涂鴉的一部分。 (這里沒有解決方案–完全是對問題啟發(fā)的思想探索。因此,代碼有些粗略,不應(yīng)用于決定是否邀請我參加面試(除非給您留下深刻的印象): http ://github.com/beargiles/projecteuler。

翻譯自: https://www.javacodegeeks.com/2014/07/getting-an-infinite-list-of-primes-in-java.html

自然數(shù) 素數(shù) 質(zhì)數(shù)

總結(jié)

以上是生活随笔為你收集整理的自然数 素数 质数_在Java中获取素数的无限列表的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 中出一区| 亚洲www久久久 | 国产一区二区精品在线 | 懂色av一区二区三区免费观看 | 久久久久精 | 爱草在线 | 羞羞网站在线观看 | 欧美性猛交xxx乱大交3 | 国产高中女学生第一次 | 久操福利在线 | 国产精品黑人一区二区三区 | 欧美精品在线观看一区二区 | 中文字幕超清在线观看 | 草草影院地址 | 上原亚衣在线观看 | 一级网站在线观看 | 性欧美8khd高清极品 | 日韩毛毛片 | 在线观看福利片 | 91青青操 | 亚洲黄色激情视频 | 欧美极品jizzhd欧美爆 | 国产一区二区三区视频 | 中文字幕女同女同女同 | 国产亚洲精品成人av在线 | 九色porny视频 | 丰满孕妇性春猛交xx大陆 | 欧美日韩精品一区 | 91丨九色丨国产 | 久久九九久久九九 | 欧美久久久 | 亚洲九九夜夜 | 国产激情在线视频 | 美女福利一区 | 日韩综合在线观看 | 日本熟妇毛茸茸丰满 | jizz在线观看视频 | 91视频免费视频 | 天天插夜夜爽 | 奇米影视久久久 | 噜噜噜精品欧美成人 | 日韩欧美亚洲天堂 | 黄色在线资源 | missav|免费高清av在线看 | 免费人成网站 | 亚洲国产一二三 | 国产美女精品久久久 | 亚洲一区二区色图 | 久久看av | 日韩欧美亚洲一区二区 | 国产成人午夜精华液 | 中国极品少妇xxxxx | 在线观看日本网站 | 精品成人无码一区二区三区 | 激情小视频 | 欧美人妖乱大交 | 五月天亚洲综合 | 伊人69| www.五月激情 | 精品人妻一区二区三区免费 | 丰腴饱满的极品熟妇 | 美女露隐私网站 | 黄色av大片 | 色老头在线视频 | 国产视频精品免费 | 午夜精品久久久久久久99黑人 | www夜片内射视频日韩精品成人 | 国产九九在线 | 北京富婆泄欲对白 | 欧美一级视频 | 中文一二三区 | 国外成人性视频免费 | 日韩视频一二三 | 亚洲欧美国产高清 | av大片网站 | 成年人av在线播放 | 国产免费成人在线视频 | va婷婷| 国产成人免费 | 蜜桃精品视频在线 | 欧美日韩视频免费 | 一级特黄肉体裸片 | www.69av.com| 一级黄色片看看 | 四虎成人av| 精品国产免费一区二区三区 | caoporn视频在线 | www.色就是色 | 人人射人人干 | 一二三四国产精品 | 天天操免费视频 | 男人天堂综合网 | 亚洲成人网在线观看 | 99久久婷婷国产综合精品草原 | 伊人成人22 | 久久h| 国产寡妇色xxⅹ交肉视频 | 免费av在线电影 | 东北高大丰满bbbbzbbb |