Frage

Für eine Bibliothek, ich brauche die ersten Primzahlen Zahlen zum Speichern von bis zu einer Grenze L. Diese Sammlung muss eine O haben (1) Lookup-Zeit (um zu überprüfen, ob eine Zahl eine Primzahl ist oder nicht) und es muss einfach sein, da eine Zahl, die nächste Primzahl zu finden (vorausgesetzt, es ist kleiner als L).

Da L befestigt ist, ein Eratostene Sieb um die Liste zu erzeugen, ist in Ordnung. Gerade jetzt, ich benutze eine gepackte boolean-Array die Liste zu speichern, die nur Einträge für ungerade Zahlen zwischen 3 und L (einschließlich) enthält. Dies geschieht (L-2) / 2 Bits an Speicher. Ich möchte in der Lage sein, zu statisch L zu erhöhen, ohne mehr Speicher.

Gibt es eine Datenstruktur mit weniger Speicher mit ähnlichen Eigenschaften? Oder zumindest mit der konstanten Lookup-Zeit? (Ungerade Zahlen können dann aufgezählt werden, bis wir eine erstklassige bekommen)

(die Sprache, die ich dies in schrieb Factor aber diese Frage wäre das gleiche in jeder Sprache sein, die hat eingebaute oder gepackte Bitfelder leicht programmierbar)

War es hilfreich?

Lösung

Sie können explizit mehr Primzahlen überprüfen Redundanz zu entfernen.

Im Moment tun Sie dies nur für zwei, von zwei explizit für Teilbarkeit prüft und dann nur für ungerade Zahlen zu speichern, ob sie prim sind.

2 und 3 Sie Reste 0 bis 5 erhalten, von denen nur 1 und 5 sind nicht teilbar durch zwei oder drei und zu einer Primzahl führen kann, so dass Sie bis zu 1/3.

2, 3 und 5 erhalten Sie 8 Zahlen von 30, was schön ist in einem Byte zu speichern.

Dies wird näher erläutert hier .

Andere Tipps

Eine Alternative zu gepackten Bitmaps und Rädern - aber ebenso effizient in bestimmten Kontexten - die Unterschiede zwischen aufeinander folgenden Primzahlen speichert. Wenn Sie die Nummer 2 wie gewohnt auslassen, dann sind alle Unterschiede sogar. Speichern von Differenz / 2 Sie können bis zu 2 ^ 40ern Regionen erhalten (kurz vor 1999066711391) Byte-Größe Variablen.

Die Primzahlen bis 2 ^ 32 erfordern nur 194 MByte, im Vergleich zu 256 MByte für eine Odds-only gepackte Bitmap. Iterieren über delta-gespeicherten Primzahlen ist viel schneller als für Radfahr Lagerung, die das Modulo-2-Rad als odds-Bitmap nur bekannt, enthält.

Für reicht von 1999066711391 ab, größere Zellgröße oder variabler Länge Speicher benötigt. Letzteres kann sehr effizient sein, wenn auch sehr einfache Systeme verwendet werden (zB halten, bis ein Byte Hinzufügen <255 hinzugefügt wurde, wie in

Vielleicht ein Trie Datenstruktur, die nur die Primzahlen enthält, ist, was Sie suchen . Anstelle von Zeichen als Indizes verwenden könnten Sie die ganze Zahl Ziffern verwenden. Eine Implementierung hierfür sind Judy-Array s.

Altough, erfüllen sie nicht Ihre O (1) Anforderung, sie sind extrem speichereffizient für ähnliche Tasten (wie die meisten Teile von Zahlen sind) und ziemlich schnell mit einem O (m) zu sehen (m = Tasten- Länge) bei maximaler.

Wenn Sie in der vorab generierten Baum für eine Primzahl aussehen, können Sie den Baum gehen, bis Sie es finden, oder Sie sind bereits an dem Knoten, die dem vorhergehenden und folgenden prime nächsten ist.

Da Speicher so billig sind, ich glaube nicht, dass Sie aus einer Geschwindigkeit Perspektive als Ihre bestehenden Regelung viel besser machen können.

Wenn es eine bessere Lösung, dann gehe ich davon würde es Vorteil des Primzahltheorems nehmen würde , die zeigt, dass als L wird größer, die Grenze von

π (L) / (L / ln (L)) nähert sich 1.

Vielleicht eine bessere Lösung wäre eine adaptive Verpackungslösung in einer Datenstruktur hat wie eine Art überspringen .

Wie wäre es irgendeine Art von Hash-Tabelle?

Sie müssen eine sehr gute Hash-Funktion. (So etwas wie n mod p, wo p nicht ein Vielfach von einem des q niedrigsten Primzahlen - wähle q ausreichend hoch, um die Anzahl der Kollisionen zu minimieren)

Wie über einen Intervall-Baum? http://www.geeksforgeeks.org/interval-tree/

Es kann nicht sein, O (1), aber es ist wirklich schnell ist. Wie vielleicht O (log (p (n))), wobei p (n) die Anzahl der Primzahlen bis zur Zahl n. Auf diese Weise können die Speicher werden Sie nur im Verhältnis zu der Anzahl der Primzahlen sein müssen wird, erheblich die Speicherkosten senken.

Zum Beispiel: Angenommen, Sie ein erstklassige bei etwa p1 finden und dann dem nächsten bei p2, Legen Intervall (P1, P2) und so weiter, und wenn Sie eine Suche nach einem beliebigen Anzahl in diesem Bereich führen wird dieses Intervall zurückkehren und Sie können p2 zurück, die die Antwort in Ihrem Fall wäre.

Wenn Sie herausfinden können, welche sind Mersenne oder andere leicht vertreten Primzahlen, Sie möglicherweise kann unter Verwendung dieser Darstellung mit einer Flagge für anwendbar Zahlen ein paar Bits speichern.

Auch, wie etwa die Zahlen als die Differenz von der vorherigen Zahl zu speichern? Dann steigt die Größe sollte nicht ganz so schnell (aber Lookup wäre langsam). oben mit dem kombinierten Ansatz aus, Sie Mersenne-Primzahlen und die Differenz aus dem letzten Mersenne-Primzahl speichern könnten.

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