reborn: Effizientes Finden eines längsten Substrings

Beitrag lesen

Hallo,

abgesehen davon, dass ich die Vorgehensweise nicht als effizient ansehe ...

ohne deine Umgebung zu kennen würde sagen splitten + sortieren.
Würde ich auch sagen, mit geeigneter RegEx splitten und nach Länge sortieren.
Dürfte trotz RegEx schneller und v.a eleganter sein als Zeichenweise durchlaufen.

... ist splitten natürlich überflüssig, wenn Finden aller Treffer ausreicht:

Wir durchsuchen den Heuhaufen

$haystack = 'ghghggghgghghghhhhhhhhhhhgghghghghghgh';

nach dem Auftreten einer Folge von beliebig vielen,

mindestens jedoch einem "h" (der Nadel).

Die Gierigkeit von RegExp kommt uns dabei entgegen :-)

Nicht beachtet: [link:http://de2.php.net/manual/de/reference.pcre.pattern.modifiers.php@title=UTF-8-Problematik].

$pattern  = '/h+/';

Wir bereiten ein Array für das Ergebnis unserer Suche vor.

$matches  = array();

und lassen alle Folgen von h finden,

alle Treffer sind wegen PREG_PATTERN_ORDER in $matches[0] (einem Array)

if ([link:http://www.php.net/manual/de/function.preg-match-all.php@title=preg_match_all]($pattern, $haystack, $matches, PREG_PATTERN_ORDER)) {
    # Wenn kein Fehler auftrat und es Treffer gab
    [link:http://de2.php.net/manual/de/function.rsort.php@title=rsort]($matches[0], SORT_STRING);   # sortiere von längster nach kürzester
    echo $matches[0][0];               # und gebe die längste aus
}


>   
> Problemlos in ein Funktionchen umzubauen, die Heuhaufen und Nadel (der zu suchende Buchstabe) entgegennimmt und die längste Kette zurückgibt.  
> Ein Ansatz:  
> ~~~php
  

> /*  
>     Durchsucht die Zeichenkette $haystack nach dem Muster $pattern und gibt  
>     die längste Übereinstimmung zurück. Wird das Muster nicht gefunden, so  
>     wird eine leere Zeichenkette zurückgegeben.  
> */  
> function biggest_substring($pattern, $haystack) {  
>     $result  = '';                     # fürs Ergebnis  
>     $matches = array();                # Zwischenlager  
>     if (preg_match_all($pattern, $haystack, $matches, PREG_PATTERN_ORDER)) {  
>         rsort($matches[0], SORT_STRING);  
>         $result = $matches[0][0];  
>     }  
>     return $result;  
> }

Aber: Sortieren ist lahm und - wie Martin gezeigt hat - überflüssig.

Freundliche Grüße

Vinzenz

Huhu,

leider kenne ich mich mit php nicht so gut aus aber das sieht sehr formschön aus, was du da gepostest hast. Ich bin aber der Meinung, dass bei der Programmierung zur Lösung einer Problemstellung zuerst ein Konzept erstellt werden sollte. Performance ist sicherlich ein Punkt, den man berücksichtigen sollte aber letztendlich braucht man das Rad nicht immer wieder neu zu erfinden und wenn schon gewisse Funktionatitäten zur Verfügung stehen, dann sollte man diese auch nutzen. Ein Grundkonzept zur Lösung der Problemstellung war und ist ja immernoch splitten + sortieren.

Warum?

1. Splitten  => aufteilen in Bestandteile
2. Sortieren => anordnen nach Regeln

Das ist erstmal nur ein Grundmuster und wiedersprich letztendlich auch keiner Implementierung, wie auch immer diese aussehen mag.

Weiterhin muss man für die Implementierung verschiedenen Faktoren berücksichtigen, die auch das Funktionsverhalten beinflussen.

1. Ist die Eingabe variabel? (wurde ja schon geklärt)
2. Was soll geschehen, wenn es keine längste Wiederholung gibt?

Meines Erachtens ist die Sortierung das kleinere Übel, denn ein Längenvergleich findet auf jedenfall statt. Von mir aus kann eine Sortierung auch durch eine Max-Funktion ersetzt werden aber man bedenke Punkt 2 => ist eine Max-Funktion eindeutig?

Jetzt wo ich so drüber nachdenke ^^ würde ich folgende Schritte durchführen (wie auch immer).

1. Splitten (Aufteilen)
2. Gruppieren nach Länge
3. Sortieren nach Länge (Gruppierung)
4. Auswahl über Schlüssel (wer ist in der Gruppe mit den meisten Wiederholungen)
5. Prüfen ob eindeutig

LG