Python: Beschleunigung der Entfernung jedes n-ten Elements aus der Liste

8

Ich versuche dieses Programmierrätsel zu lösen und obwohl die Lösung (siehe Code unten) funktioniert richtig, es ist zu langsam für die erfolgreiche Einreichung.

  • Irgendwelche Zeiger, wie man das macht schneller (Entfernen jedes n-ten Elements aus einer Liste)?
  • Oder Vorschläge für einen besseren Algorithmus, um dasselbe zu berechnen; Anscheinend kann ich an nichts denken anders als Brute-Force für jetzt ...

Grundsätzlich ist die Aufgabe:

%Vor%

Mein Originalcode (er berechnete die 3000 ersten Glückszahlen in etwa einer Sekunde auf meinem Rechner - leider zu langsam):

%Vor%

EDIT: Dank der tollen Beiträge von Mark Dickinson, Steve Jessop und gnibbler, kam ich zu folgendem, das ziemlich viel schneller ist als mein ursprünglicher Code (und erfolgreich bei < a href="http://www.spoj.pl"> Ссылка mit 0,58 Sekunden!) ...

%Vor%     
ChristopheD 18.03.2010, 22:14
quelle

5 Antworten

7

Diese Serie wird spielerische Zahlen

genannt

__delslice__ sollte schneller sein als __setslice__ + filter

%Vor%

So wird die Schleife.

%Vor%

Was in weniger als 0,1 Sekunden läuft

    
John La Rooy 19.03.2010, 03:27
quelle
4

Versuchen Sie, diese beiden Zeilen zum Löschen und Filtern zu verwenden, anstatt, was Sie haben; filter(None, ...) läuft erheblich schneller als filter(lambda ...) .

%Vor%

Bearbeiten: viel besser, einfach del sieve[::item] ; Siehe gnibbler's Lösung.

Sie können möglicherweise auch eine bessere Abbruchbedingung für die while-Schleife finden: Wenn beispielsweise das erste verbleibende Element im Sieb i ist, werden die ersten i -Elemente des Siebs zum nächsten i Glückszahlen; also wenn len(luckynumbers) + sieve[0] >= wanted_n , du hättest die Zahl, die du brauchst, schon berechnet --- du musst nur herausfinden wo in sieve ist, damit du es extrahieren kannst.

Auf meinem Computer läuft die folgende Version Ihrer inneren Schleife um das 15-fache schneller als Ihr Original, um die 3000. Glückszahl zu finden:

%Vor%     
Mark Dickinson 18.03.2010 22:58
quelle
2

Eine Erklärung, wie Sie dieses Problem lösen können, finden Sie hier . (Das Problem, zu dem ich verlinkt habe, verlangt nach mehr, aber der Hauptschritt in diesem Problem ist der gleiche wie der, den du lösen willst.) Die Site, mit der ich verlinkt habe, enthält auch eine Beispiellösung in C ++.

Die Menge der Zahlen kann in einem Binärbaum dargestellt werden, der die folgenden Operationen unterstützt:

  • Liefert das n th Element
  • zurück
  • Löschen Sie das Element n th

Diese Operationen können so implementiert werden, dass sie in O(log n) time ausgeführt werden, wobei n die Anzahl der Knoten in der Struktur ist.

Um die Struktur zu erstellen, können Sie entweder eine benutzerdefinierte Routine erstellen, die die Struktur aus einem gegebenen Array von Elementen erstellt, oder eine Einfügeoperation implementieren (stellen Sie sicher, dass die Struktur ausgeglichen bleibt).

Jeder Knoten in der Struktur benötigt folgende Informationen:

  • Zeiger auf die linken und rechten Kinder
  • Wie viele Elemente gibt es in den linken und rechten Teilbäumen

Wenn eine solche Struktur vorhanden ist, sollte die Lösung des restlichen Problems ziemlich einfach sein.

Ich empfehle auch, die Antworten für alle möglichen Eingabewerte zu berechnen, bevor eine Eingabe gelesen wird, anstatt die Antwort für jede Eingabezeile zu berechnen.

Eine Java-Implementierung des obigen Algorithmus wird in 0,68 Sekunden auf der von Ihnen verlinkten Website akzeptiert.

(Entschuldigung, dass Sie keine Python-spezifische Hilfe bereitstellen, aber hoffentlich wird der oben beschriebene Algorithmus schnell genug sein.)

    
Anonym Mus 18.03.2010 23:28
quelle
1

Es ist besser, ein Array zu verwenden und jedes Nth Item mit dieser Strategie auf Null zu setzen; Nachdem Sie dies einige Male hintereinander getan haben, werden die Aktualisierungen immer schwieriger, sodass Sie das Array neu formatieren müssen. Dies sollte die Geschwindigkeit um mindestens einen Faktor 10 verbessern. Brauchen Sie viel besser als das?

    
Rex Kerr 18.03.2010 22:26
quelle
0

Warum erstellen Sie nicht einfach eine neue Liste?

%Vor%     
dan04 19.03.2010 02:38
quelle

Tags und Links