Frage

Was ist die beste Datenstruktur (in Java) für die Aufgabe des Ladens 51 Millionen Primzahlen und Iterieren dann über sie?

Ich muß wissen, zum Beispiel, die Primzahlen, die zwischen 1000000000 und der gleichen Zahl minus 100000 sind.

War es hilfreich?

Lösung

Eine binäre Suche wird für diese Daten nicht wunderbar sein würde, da die erste Hälfte der Primzahlen zueinander als die letzte Hälfte von ihnen näher sein werden.

Vielleicht haben Sie sich auf Ihre Suche verbessern, indem sie wissen, wie viele Primzahlen gibt es unter x . Vielleicht den Schnitt schräg durch die Annäherung in der Verbindung erwähnt werden.


Mein erster Versuch wäre dies. Ich würde zwei Arrays haben.

  1. Ein Array aller Primzahlen.
  2. Ein Array, das mir, wo in der ersten Reihe erzählt die erste Primzahl über 1000 * n war. Also, wenn ich die erste Primzahl mit einem Wert von 5000 oder mehr finden will, ich second aussehen würde [5000 / 1000-1].

ich eine grobe Position mit Array bekommen 2, bevor sie mit Array etwas zu tun 1.

Andere Tipps

Warum speichern sie überhaupt in einer Karte? Ist das so Sie schnelles Nachschlagen zu sehen, ob eine gegebene Zahl eine Primzahl ist? Das würde Sinn machen und geben Ihnen einen schnellen Zugriff. Die Kosten für deren Zugabe kann gemildert werden (aber nicht eliminiert), indem die Anfangskapazität der TreeMap Einstellung. Dies wird jedoch immer noch Baum Rebalancing Kosten entstehen.

Ein alternativer Speicher könnte einfach sein, sie zu sortieren und sie in einem Array setzen. Dies wird Ihnen O (log n) Lookup mit einer Halbierungs Suche wird aber immer Bereiche trivial machen. Sie können Arrays.binarySearch () .

Da Sie alle Primzahlen vorberechnen können, und (von der Primzahlsatz, dass Nosredna und andere erwähnt haben) Sie wissen, wie viele es sein wird, können Sie eine feste Struktur verwenden (int []) und einmalig in -dem Einführungskosten sollten kein Problem sein.

Binary-Suche (Wie Arrays.binarySearch ()), so wird schnell Sie wahrscheinlich nicht brauchen, Optimierungen zu berücksichtigen. Aber man könnte auch die Primzahltheorems Vorhersagen von etwa verwenden, in denen der N-te Primzahl ist die Endpunkte von Bereichen noch schneller zu finden.

Just, anders zu sein, ich werde, dass Sie auch die Primzahlen in diesem Maßstab weisen darauf hin, wie gesetzten Bits in einem großen Bit-Feld speichern kann, wo, wenn N eine Primzahl ist, Bit #N zu 1. Die Struktur tatsächlich gesetzt würde kleiner als der int [] - 1 Milliarde Bits ~ 110MiB, während 51 Millionen ints ist ~ 200MiB. Siehe die Klasse BitSet. Da kein sogar Indizes Prime sind, können Sie eine Unterklasse oder BitSet wickeln die triviale Antwort für alle geraden Indizes und Halb / double-Werte als angemessen zu geben, bevor er zu / von BitSet, und speichern so das ganze Feld in ~ 55MiB.

Testen einer Primzahl mit einer Struktur, ist O (1), aber alle über die gesetzten Bits Iterieren (Primzahlen) hängt von der Dichte der Primzahlen im Bereich Sie gezielt haben. Es sollte immer noch, obwohl ziemlich schnell sein.

Es scheint mir, dass ein einfaches Array (oder Arraylist, da es einfacher ist, mit zu arbeiten) wäre in Ordnung. Hinzufügen von Elementen ist O (1), und Sie können alle Primzahlen zwischen x und y erhalten, indem eine binäre Suche für die erste Primzahl tun> = x (siehe http://java.sun.com/j2se/1.5.0 /docs/api/java/util/Collections.html#binarySearch%28java.util.List,%20T%29 ), und dann gehen Sie einfach durch die Liste, bis Sie auf eine Primzahl> y erhalten.

(Ich weiß, cletus schlug mich, aber hoffentlich das zusätzliche Detail ist von Nutzen.)

Der n-te Primzahl ist über p(n) ~ n ln(n), dh

p(51E6) ~ 905114146 < 2147483647 = Integer.MAX_VALUE

Das bedeutet, der effizienteste Weg, um die ersten 51 Millionen Primzahlen zu speichern ist ein int[].

Es hängt davon ab, genau das Gleichgewicht der Operationen und Nutzung. Eine einfache sortierte Array wird am besten sein, für die Primzahlen zu speichern.

Nun, wenn die Leistung wirklich an erster Stelle steht und Speicherkosten unbedeutend ist, dann können Sie dies mit einem Index von Indizes erweitern. z.

int MAX_NUM_PRIMES =    ...   // the maximum number of primes to be stored
int MAX_PRIME = ....          // the largest prime to be stored
int primes[MAX_NUM_PRIMES]    // array of prime numbers, sorted
int nextPrime[MAX_PRIME]      // nextPrime[i] is the index of the next prime >= i

where nextPrime[i] is the starting point in the array primes for the first prime > i.

then, to iterate over e.g.   2000 primes from   3456, you would do

int j = nextPrime[3456]
for (i = j; i < j + 2000; i++) {
    int x = prime[i];
    ... do whatever with x ...
}
  

Ich muß wissen, zum Beispiel, die Primzahlen, die zwischen 1000000000 und der gleichen Zahl minus 100000 sind.

Dann durch ein Sieb bauen für genau die Zahlen, die Sie interessieren. Computing alle Primzahlen unter ist eine Verschwendung, wenn Sie nicht genau wissen wollen, wie viele Primzahlen gibt es unter 999.900.000.

Eine gute Datenstruktur für diese Größe von Zahlen ist ein Bit gesetzt. Da etwa ein in 21 Zahlen eine Primzahl ist, dauert es weniger Speicher als die Zahlen explizit zu speichern, und es ist schnell genug für Iterieren durch Bereiche.

Edit:. Um konkret zu sein, auf meinem Laptop in Java die gesamte Palette Sieben dauert etwas mehr als eine Minute, die letzten 100000 etwa 30 Millisekunden Sieben

Wenn Sie die beste Datenstruktur wollen schnell die Anzahl der Primzahlen zwischen x und y zu finden (wie in Ihrem Beispiel) Sie möchten ein Binary Indexed Baum .

Es gibt eine gute Beschreibung hier .

Dieses Java-Applet scheint ziemlich schnell: Tabelle der Primes von 1 bis 1 000 000 000 000 http://www.walter-fendt.de/m14e/primes.htm (keine Quelle obwohl, aber Sie könnten den Autor versuchen)

Eine Reihe von Zahlen werden wahrscheinlich gut tun:)

Das Problem könnte das Array werden zu erzeugen? In diesem Fall erzeugt ein Objekt das Array enthält, und füllt ihn (durch Erzeugung oder aus einer Liste von Primzahlen Lese). Wenn Sie fertig sind, serialisiert es auf die Festplatte so das Programm den binären Strom schnell in der Zukunft das Array laden lesen kann.

Sehen Sie diese Frage für Variationen auf, wie das Prime-Array zu erzeugen: Primzahlberechnung Spaß

Durch Ihre Anforderung, sollten Sie das Segmented Sieb des Eratosthenes verwenden. es wird nicht eine große Menge an Speicher benötigen ..

Alle Primzahlen bis zu der Quadratwurzel 999900000. (~ 31.621) die sich leicht in einem Array gespeichert werden können.

Nun Führen Sie den Sieve-ing-Prozess über ein 100000-Länge-Array. mit diesen Primzahlen.

sehr effizient, für eine große Zahl.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top