[QUIZ#1] ThE_-_BliZZarD (PHP)


#1
Aktuelle Version: 0.69 RC3

Erklärung zur Eigenarbeit:
Ich bestätige hiermit, dass alle im folgenden Quellcode vorgestellten Funktionen, außer den PHP-eigenen, von mir entworfen und implementiert wurden und ich keinerlei geistiges Eigentum Dritter verwendet habe.

ToDo:
  • Vielleicht in eine Klasse einbauen.. aber.. wozu?

ChangeLog:
  • 0.69 RC3 Änderungen:
    • Dokumentation hinzugefügt (im Folgenden Text)
    • Beispiel hinzugefügt
    • BugFix: Highlighten funktioniert nun korrekt
  • 0.68 RC2 Änderungen:
    • Markierung eingefügt
  • 0.66 RC1 Erste funktionsfähige Version


Mein Lösungsansatz besteht aus einer einfachen Anhäufung von Funktionen, die ich zuerst kurz vorstellen und erläutern werde, im Anhang findet sich der Sourcecode.

Dokumentation:
  • Funktionsübersicht:
PHP:
function UnscharfeSuche($searchPattern, $searchArray)
function PatternMatchesString($searchPattern, $searchIn)
function StringToArray($string)
function DeleteUnmentionedChars($string, $knownChars)
function IsCharInArray($char, $knownChars)
function FormatSearchResult($result, $searchPattern, $useHTML = TRUE, $highlightHits = TRUE, $highlightPre = "<", $highlightPost = ">")
function HighlightHits($result, $searchPattern, $highlightPre = "<", $highlightPost = ">")
  • Funktionserläuterungen:
    Hinweis: Als Hauptfunktionen gelten die Funktionen, welche vom übergeordneten Script direkt aufgerufen werden
    • Funktion UnscharfeSuche (Hauptfunktion)
      • Parameter:
        $searchPattern - Die Suchanfrage, z.B. "JFK"
        $searchArray - Ein Array mit den zu durchsuchenden Elementen, z.B. die Ausgabe von file()
      • Rückgabe:
        array - im Format:
        $results[' count '] - Anzahl der Ergebnisse
        $results[' elements '] - Enthält die passenden Ergebnisse
      • Erklärung:
        Diese Funktion ist die Hauptfunktion. Sie wird mit dem Suchmuster und den zu durchsuchenden Daten aufgreufen, zurück gibt es ein Array mit der Anzahl der Ergebnisse und den String aus dem $searchArray, welche auf das Suchmuster passen
    • Funktion PatternMatchesString
      • Parameter:
        $searchPattern - Das Suchmuster in string-Form
        $searchIn - Der String der gegen das Muster gematched werden soll
      • Rückgabe:
        boolean - Ein boolescher Wert, ob der String mit dem Suchmuster matched.
      • Erklärung:
        Ermittelt, ob das Suchmuster $searchPattern auf den gelieferten String $searchIn passt, liefert im Erfolgsfall TRUE, sonst FALSE zurück
    • Funktion StringToArray
      • Parameter:
        $string - Der String der in ein Array umgewandelt werden soll
      • Rückgabe:
        array - Ein Array mit Länge-des-Strings Elementen, bestehend aus den einzelnen Zeichen des Quellstrings $string
      • Erklärung:
        Konvertiert einen String in ein ein-Zeichen Array.
    • Funktion DeleteUnmentionedChars
      • Parameter:
        $string - Der String der auf die wichtigen Zeichen reduziert werden soll
        $knownChars - Suchmuster, d.h. die bekannten und erwünschten Zeichen
      • Rückgabe:
        string - Fertig bearbeiteter String
      • Erklärung:
        Entfernt die für den Suchvorgang unrelevanten Zeichen aus dem String
    • Funktion IsCharInArray
      • Parameter:
        $char - Zu prüfendes Zeichen
        $knownChars - Suchmuster in Arrayform
      • Rückgabe:
        boolean - Wenn Zeichen enthalten TRUE, sonst FALSE
      • Erklärung:
        Durchsucht das Suchmuster nach dem gegebenen Zeichen $char
    • Funktion FormatSearchResult (Hauptfunktion)
      • Parameter:
        $result - Der Rückgabewert von UnscharfeSuche()
        $searchPattern - Das Suchmuster nach dem gehighlightet werden soll
        $useHTML - Soll HTML in der Ausgabe verwendet werden
        $highlightHits - Sollen Treffer markiert werden
        $highlightPre - Mit was soll ein gefundener Treffer vor-markiert werden
        $highlightPost - Mit was soll ein gefundener Treffer nach-markiert werden
      • Rückgabe:
        string - Das formatierte Ergebnis
      • Erklärung:
        Formatiert das Ergebnis der Suche für eine Ausgabe
    • Funktion HighlightHits
      • Parameter:
        $result - Die zu highlightende Zeile
        $searchPattern - Das zu verwendende Suchmuster
        $highlightPre - Was vor einen Treffer gesetzt werden soll
        $highlightPost - Was nach einen Treffer gesetzt werden soll
      • Rückgabe:
        string - Der gehighlightete String
      • Erklärung:
        Sucht nach den relevanten Vorkommen von $searchPattern und markiert diese.

Verwendung/Aufruf und Suche:
PHP:
$array = file("./presidents.txt"); // Das für die Aufgabe als Beispiel beigelegte Textfile mit den Präsidenten

$searchPattern = "GB"; // Das zu suchenden Muster - kann sonst wo her eingelesen werden.

echo FormatSearchResult(UnscharfeSuche($searchPattern, $array), $searchPattern, TRUE); // Suchen und Ausgeben!
Sourcecode:
PHP:
function UnscharfeSuche($searchPattern /* e.g. "ooo" or "George Bush" */, $searchArray /* An array with one result-line per element */){
	$results = array( 'count' => 0, 'elements' => array());
	/*
		Format der Results:
		$results[' count ']    - Anzahl der Ergebnisse
		$results[' elements '] - Enthält die passenden Ergebnisse
	*/

	if (strlen(trim($searchPattern)) == 0) {
		// Wir haben kein Suchmuster - d.h. keine Ergebnisse!
		return $results;
	}elseif (count($searchArray) == 0) {
		// Wir haben keine Elemente in denen wir suchen können!
		return $results;
	}else {
		foreach ($searchArray AS $value) {
			if (strlen(trim($value)) > 0 /* Test if this is an empty line */) {
				if (PatternMatchesString($searchPattern, $value)) {
					$results['count'] += 1;
					$results['elements'][] = $value;
				}
			}
		}
		return $results;
	}

}

function PatternMatchesString($searchPattern /* SearchPattern in Stringform */, $searchIn /* The string in which we search*/) {
	$searchPattern = StringToArray($searchPattern);
	$searchIn  = DeleteUnmentionedChars($searchIn, $searchPattern);
	if ((strlen($searchIn) > 0) AND (count($searchPattern) > 0)) {
		$pos = (-1); //Anfangsbelegung
		for ($i = 0; $i < count($searchPattern); $i++) {
			if ($pos == (-1)) {
				if (($pos = strpos($searchIn, $searchPattern[$i])) === FALSE) {
					return false;
				}
			}else {
				if (($pos = strpos($searchIn, $searchPattern[$i], $pos+1)) === FALSE) {
					return false;
				}
			}
		}
		return true;
	}else {
		return false;
	}
}

// Converts a string to a simple array
function StringToArray($string /* e.g. "George Bush" */){
	$result = array();
	if (strlen($string) > 0) {
		for ($i = 0; $i < strlen($string); $i++) {
			$result[] = substr($string, $i, 1);
		}
	}
	return $result;
}

// Deletes unwanted characters from the searchstring. After this operation we got only those chars left that are included in the searchstring
function DeleteUnmentionedChars($string /* e.g. "George W. Bush" */, $knownChars /* An Array with one character per element */){
	$result = "";
	if (strlen($string) > 0) {
		for ($i = 0; $i < strlen($string); $i++) {
			if (IsCharInArray(substr($string, $i, 1), $knownChars)) {
				$result .= substr($string, $i, 1);
			}
		}
	}
	return $result;
}

function IsCharInArray($char /* eg. "G" */, $knownChars /* An Array with one character per element */){
	if (array_search($char, $knownChars) === FALSE) {
		return false;
	}else {
		return true;
	}
}

// Returns a string
function FormatSearchResult($result, $searchPattern, $useHTML = TRUE, $highlightHits = TRUE, $highlightPre = "&lt;", $highlightPost = "&gt;"){
	$searchPattern = StringToArray($searchPattern);
	if ($useHTML) {
		// Format with <br>\r\n
		$format = "<br>\r\n";
	}else {
		// Format with \r\n
		$format = "\r\n";
	}
	$return = "";
	if ($result['count'] > 0) {
		$return .= "Die Anfrage ergab ".(($result['count'] == 1) ? "einen" : $result['count'])." Treffer:".$format;
		foreach ($result['elements'] AS $value) {
			$return .= ($highlightHits ? HighlightHits($value, $searchPattern, $highlightPre, $highlightPost) : $value).$format;
		}
	}else {
		$return .= "Die Anfrage ergab keine Treffer!";
	}
	return $return;
}

// Highlights the elements of the searchpattern in the String
function HighlightHits($result, $searchPattern, $highlightPre = "&lt;", $highlightPost = "&gt;"){
	if ((strlen($result) > 0) AND (count($searchPattern) > 0)) {
		$return = "";
		for ($i = 0; $i < strlen($result); $i++) {
			if (IsCharInArray(substr($result, $i, 1), $searchPattern)) {
				$return .= $highlightPre.substr($result, $i, 1);
				$j = $i + 1;
				while (($j < strlen($result)) AND IsCharInArray(substr($result, $j, 1), $searchPattern)) {
					$return .= substr($result, $j, 1);
					$j++;
					$i++;
				}
				$return .= $highlightPost;
			}else {
				$return .= substr($result, $i, 1);
			}
		}
	}else {
		return false;
	}
	return $return;
}
 

Anhänge

Zuletzt bearbeitet:
#2
Wow, die Dokumentation finde ich absolut genial.

Schoen waere noch gewesen, vielleicht am Ende des Posts, oder sogar in einem 2. Post, den gesamten Code zu sehen, also die Implementation der Funktionen.
So braucht man dann das Zip-File nicht runterladen um den Code anzuschauen. ;)
 
#3
Danke für den Tipp, habe den Source eingefügt.

Zu der Dokumentation: Ist eigentlich Standart - ich frage mich wieso das hier sonst keiner macht..^^ Also wenns nicht irgendwie gefordert wird lass ich es demnächst weg.. aber eigentlich ist sowas Pflicht.
 
#4
Naja, ich denk wenn wir's Pflicht machen duerfte es ein paar Leute abschrecken.
Der Coder an sich ist ja gern dokumentierfaul. ;)

Dennoch wuerde ich ein solches Format hier gern oefter sehen. Vielleicht nicht ganz so "hardcore", aber irgendwie in diese Richtung.

Ein Fleisskaertchen kriegst Du aber trotzdem. ;)
 
#5
ACK, außerdem gut strukturiert und sprechende Variablen- und Funktionsnamen, das macht das Ganze sehr gut lesbar. Auch von mir ein Fleisskärtchen. ;)

Du wolltest ja auch noch etwas zur Länge Deines Codes hören. Was sofort auffällt: An einigen Stellen hast Du unnötigen Aufwand betrieben.

1. Statt Deiner Funktion StringToArray() kannst Du einfach [phpf]str_split[/phpf] verwenden.

2. Wenn Du den input-String und das Suchmuster jeweils in ein Array umwandelst, kannst Du die irrelevanten Zeichen z.B. mit [phpf]array_intersect[/phpf] herausfiltern. Das würde DeleteUnmentionedChars() ersetzen.

3. In der Funktion PatternMatchesString brauchst Du keine Schleife über jedes einzelne Zeichen des Suchmusters. Durch das vorherige Filtern muss das Suchwort "am Stück" in dem resulttierenden String vorkommen. Ein einfaches strpos() hätte hier gereicht.

LG
 
#6
1. Statt Deiner Funktion StringToArray() kannst Du einfach [phpf]str_split[/phpf] verwenden.

2. Wenn Du den input-String und das Suchmuster jeweils in ein Array umwandelst, kannst Du die irrelevanten Zeichen z.B. mit [phpf]array_intersect[/phpf] herausfiltern. Das würde DeleteUnmentionedChars() ersetzen.

3. In der Funktion PatternMatchesString brauchst Du keine Schleife über jedes einzelne Zeichen des Suchmusters. Durch das vorherige Filtern muss das Suchwort "am Stück" in dem resulttierenden String vorkommen. Ein einfaches strpos() hätte hier gereicht.

LG
*Fleisskärtchen sammelt*
Vielen Dank erstmal für die Hinweise :D Möglichkeiten um meine Fähigkeiten zu verbessern sind immer gut. Werde es mir morgen alles mal durchlesen, die Funktion str_split() scheint wirklich sehr praktisch zu sein. Hatte ich bis jetzt noch nie gesehen.

Zu 3.: Wieso sollte das Wort am Stück vorkommen müssen? Sucht man beispielsweise nach dem String "JFK" in dem String "Jannik Franz Ferdinand Kolumbus". Entfernt man alle unnützen Zeichen bleibt "JFFK" übrig. D.h. der Suchstring ist nicht am Stück verfügbar. Ich dachte mir, ich gehe die Suchmuster-Zeichen durch, bis ich ein Zeichen finde, welches nicht in im String verfügbar ist.. Halte ich eigentlich immer noch für die beste Vorgehensweise um die richtige Reihenfolge zu prüfen.

Warte auf weitere Diskussion xD
 

Neue Beiträge