Algorithmus zum Scannen von Zeichenketten
Wenn Sie einen schnellen Algorithmus suchen, können Sie den Algorithmus verwenden, den ich kürzlich für eine Interviewfrage entwickelt habe, bei der es um die längste Folge von aufeinanderfolgenden Buchstaben in einer Zeichenkette ging. Siehe Blogeintrag hier .
def search_longest_substring(s):
"""
>>> search_longest_substring('AABBBBCBBBBACCDDDDDDAAABBBBCBBBBACCDDDDDDDAAABBBBCBBBBACCDDDDDDA')
(7, 'D')
"""
def find_left(s, midc, mid, left):
for j in range(mid-1, left-1, -1):
if s[j] != midc:
return j + 1
return left
def find_right(s, midc, mid, right):
for k in range(mid+1, right):
if s[k] != midc:
return k
return right
i, longest = 0, (0, '')
while i < len(s):
c = s[i]
j = find_left(s, c, i, i-longest[0])
k = find_right(s, c, i, len(s))
if k-j > longest[0]:
longest = (k-j, c)
i = k + longest[0]
return longest
if __name__ == '__main__':
import random
heads_or_tails = "".join(["HT"[random.randrange(0, 2)] for _ in range(20)])
print search_longest_substring(heads_or_tails)
print heads_or_tails
Dieser Algorithmus ist O(n) im schlimmsten Fall (alle Münzwürfe sind identisch) oder O(n/m) im durchschnittlichen Fall (wobei m die Länge der längsten Übereinstimmung ist). Bitte korrigieren Sie mich in diesem Punkt.
Der Code ist nicht besonders pythonisch (d.h. er verwendet keine Listenauflösungen oder itertools
oder andere Dinge). Es ist in Python und es ist ein guter Algorithmus.
Mikro-Optimierungen
Für die Mikro-Optimierung Menge, hier sind Änderungen, die dies wirklich schreien in Python 2.6 auf einem Windows Vista Laptop machen:
def find_left(s, midc, mid, left):
j = mid - 1
while j >= 0:
if s[j] != midc:
return j + 1
j -= 1
return left
def find_right(s, midc, mid, right):
k = mid+1
while k < right:
if s[k] != midc:
return k
k += 1
return right
Zeitliche Ergebnisse für 1000 Iterationen mit timeit
:
range: 2.670
xrange: 0.3268
while-loop: 0.255
Hinzufügen von psyco
in die Datei importieren:
try:
import psyco
psyco.full()
except ImportError:
pass
0,011 bei 1000 Iterationen mit psyco
und while-Schleife. Mit vernünftigen Mikro-Optimierungen und dem Import von psyco
läuft der Code etwa 250-mal schneller.