|
1.3.1 Beispiel |
Die Mustersuche in Strings, in Zeichenketten, wird in vielen Bereichen verwendet. Textverarbeitungsprogramme, Suchmaschinen des Internets nutzen es, aber auch zum Auffinden von Gensequenzen oder Molekülstrukturen wird der Mustervergleich herangezogen. Ein solcher, alltäglicher und häufig genutzter Vorgang sollte dementsprechend nur wenig Zeit in Anspruch nehmen.
Voraussetzungen: Seien der Text A = a1a2...an und das Muster B=b1b2...bm mit n≥m Zeichenketten über einem endlichen Alphabet. Gesucht ist das erste Vorkommen von B in A, gekennzeichnet durch den Index i (Beginn des Musters im Text).
function bruteforce ( a, b: string; n, m: integer): integer; (*liefert Beginn des Musters oder -1, wenn b in a nicht vorkommt*) var: i, j: integer; begin i := 1; j := 1; repeat
inc(j); else begin
j := 1; (*Musterzeiger auf Anfang gesetzt*) (*b in a gefunden/ kein Vorkommen von b in a*) if j>m
else bruteforce := -1 |
Die Funktion 'bruteforce' ist ein sehr einfaches Suchverfahren.
Sie vergleicht Muster und Text Zeichen für Zeichen beginnend von links.
Tritt ein mismatch auf, d.h. stimmen die verglichenen Zeichen nicht überein, so wird der weitere Mustervergleich abgebrochen.
Das Muster wird um eine Stelle nach rechts verrückt und der Zeichenvergleich beginnt erneut. Zeitkomplexität:
Zusammen gerechnet führt das Programm somit 2 + (n-m+1)(m+2) + 2 aus. Es liegt in der Größenordnung von O(nm). Die äußere Schleife wird durch das Zurücksetzen von i innerhalb der Schleife ungefähr m*n-Mal ausgeführt. Die Suche von '0001' in '000000000000000001' benötigt die maximale Laufzeit. Im Regelfall jedoch arbeitet dieses Programm deutlich besser: meist wird schon beim ersten Buchstaben des Musters ein mismatch festgestellt. Der Rumpf der Schleife setzt in so einem Fall den Zähler i nicht wieder zurück. Speicherbedarf |
Der hier angegebene Algorithmus führt den Mustervergleich immer wieder um nur einen Schritt versetzt aus. Dabei werden viele überflüssige Vergleiche gemacht und der Index immer wieder zurückgesetzt, ohne das Wissen aus den bisherigen Vergleichen zu nutzen. Andere Algorithmen zur Mustersuche in Strings nutzen dieses Wissen und müssen den Index an keiner Stelle zurücksetzen. Dafür sind oft Vorarbeiten nötig, die das Muster untersuchen. Um die Untersuchungsergebnisse aufzuheben, ist weiterer Speicherplatz nötig.
Nun noch ein Überblick über die Komplexität von Programmbestandteilen:1
Rechenregeln
Einfache Anweisungen | O(1) |
Blöcke | O(Block)= O(Anweisung_1) + ... + O(Anweisung_n) |
for-Schleifen | O(1)+ (Ende-Anfang+1)*O(eingeschlossener Block) |
while/repeat-Schleifen | Induktion über Steuerblock |
Verzweigungen | O(1)+ O(größerer Block) |
Prozedur | O(1)+ O(prozedurrumpf) |
________
1 Diese Angaben berücksichtigen das universale Kostenmaß.
Jede Zuweisung verbraucht eine Einheit der Größe 1 unabhängig von der Größe der Zahl.
Beim logarithmischen Kostenmaß wird die Zahlengröße berücksichtigt.
Größere Zahlen verbrauchen mehr Zeit.
Übersicht 1 2 3 4 5 Zusammenfassung |
|