![]() |
| | Themen-Optionen | Thema durchsuchen |
| | Nach oben #2 |
| Johannes Schlichenmaier Registriert seit: 26.08.2005 Ort: Mannheim
Beiträge: 403
|
Unter der Vorraussetzung, dass a) du max. doppelte Einträge vorkommen (für mehr muss man das Konstrukt ein wenig modifizieren, wobei ich mir da garnicht mehr so sicher bin...) und b) du die doppelten Einträge dann nur einfach brauchst, also dein Endarray dann so aussieht: Code: array( [0] => "eins"
[3] => "zwei"
...
)
PHP-Code: Code: Array
(
[2] => zwei
[5] => vier
[7] => funf
)
EDIT: Ich hab das mal eingefärbt! Das stimmt leider nicht, meine Lösung, denn für array_diff spielt es keine Rolle, ob der Einträg mehrmals vorkommt. Das Ergebnis wird durchweg ein leeres Array sein. Tja, typischer Fall von nicht nachgedacht vor gepostet... EDIT 2: Ich hab ganz übersehn, dass array_unique() die Keys preserved. Also funktioniert mein Konstrukt doch mit array_diff_key(). Hab meinen Beitrag mal dahingehend editiert.
__________________ In the beginning was the word and the word was content-type: plain/text heute code ich, morgen debug ich und uebermorgen cast ich die koenigin auf int Geändert von Jojo (06.10.2008 um 22:57 Uhr) |
| | |
| | Nach oben #3 |
| neugieriger PHP-Anfäger Registriert seit: 16.08.2008 Ort: Mecklenburg-Vorpommern
Beiträge: 45
|
Ich denke, dass array_unique alle doppelten Werte löscht? Das verstehe ich jetzt nicht. Hm... Was möchte ich eigentlich machen? Lass mich mal konkreter werden: Ich habe einen String, ausgelesen aus einer Datenbank und einen weiteren String. Diese Strings werden in ihre einzelnen Worte zerschnitten. Am Ende habe ich zwei Arrays, dass erste mit Datenbankeinträgen, dass andere mit den Suchworten. Jetzt möchte ich z.B. das (Datenbank)array[0] mit dem (Suchwort) array[3] durch eine Funktion vergleichen und stelle fest, die sind sich ähnlich. Nun speicher ich den Wert aus array[0] in einem Vorschlags-Array und kann am Ende ein paar Suchvorschläge präsentieren. Wie spielt sich das ab? Stell dir vor, dass das zweite Suchwort, und das dritte Suchwort auf ein und den selben Datenbankeintrag passen, dann habe ich sie also zwei mal in meinem Array mit Suchvorschlägen. Nun möchte ich, dass die Werte, die am häufigsten vorkommen, als erstes ausgegeben werden, dann die Vorschläge mit den nächst geringeren Treffern. Ich hoffe, damit konnte ich ein wenig dabei helfen, mir zu helfen. Danke! P.S. Ich weiß, dass es für die Suche in einer Datenbank auch andere Funktionen gibt, in DIESEM Fall, wäre diese Vorgehensweise (oder eine mit ähnlicher Wirkung) aber von großem Vorteil |
| | |
| | Nach oben #4 |
| Johannes Schlichenmaier Registriert seit: 26.08.2005 Ort: Mannheim
Beiträge: 403
|
Also als erstes: Ich hab meinen ersten Beitrag mal editiert. Der macht übrigens genau das, was du im Startpost definiert hast: Gibt dir alle doppelt vorkommenden Elemente eines Arrays zurück. Das array_unique() ist nur ein Hilfskonstrukt, um das zu erreichen. Entscheidend ist das array_diff_key() Zu deiner Erklärung: Sei mir nicht böse, kann auch an der Uhrzeit liegen, aber ich werd aus deiner Erklärung nicht wirklich schlau. Es klingt ein wenig diffus... Möchtest du jetzt doppelte Einträge in einem Array ausgeben, oder möchtest du Wörter aus einer Benutzereingabe mit Keywörtern auf Ähnlichkeit überprüfen und diese dann noch nach Häufigkeit sortieren? Das sind in meinen Augen zwei paar Schuhe. Wenn du zur Zeit nur den obrigen Algoritmus brauchst, dann ist ja alles ok, andernfalls musst du deine Spezifikationen verfeinern. Dazu ein Tipp: Wörtliche Spezifikationen sind für eine reale Code-Umsetzung nicht wirklich sinnvoll. Versuch mal einen schematischen Ablauf (ein bisschen so wie in Mathe) zu erstellen. Dann lässt sich darüber leichter diskutieren. Grüße, Jojo
__________________ In the beginning was the word and the word was content-type: plain/text heute code ich, morgen debug ich und uebermorgen cast ich die koenigin auf int |
| | |
| | Nach oben #5 | |
| neugieriger PHP-Anfäger Registriert seit: 16.08.2008 Ort: Mecklenburg-Vorpommern
Beiträge: 45
|
Ich werd aus der Unique-Sache von oben immer noch nicht schlau, sorry Ich habe mir die Definitionen schon zig mal durchgelesen, aber der Groschen will irgendwie nicht fallen. Ein mathematischer Ablauf? Ich versuche es. gegeben: - Datenbankeinträge (z.B. Schlagworte bzw. Schlagwortketten) - User-Suchstring gesucht: - die Schlagworte und Schlagwortketten (Ketten=mindestens zwei Worte), welche die größte Ähnlichkeit mit dem falsch geschriebenen Suchstring haben. Ich könnte das Ganze natürlich in einer einzigen Funktion abarbeiten. zum Beispiel mit der Levenshtein-Funktion. Ich stelle mir das ganze so vor, dass die Schlagwortkette ausgelesen und in einem Array gespeichert wird. Ein Arraykästchen wird dann in seine einzelnen Worte zerlegt und in einem weiteren Array gespeichert. DIESES Array gehe ich durch und vergleiche Wort für Wort, die Wahrscheinlichkeit, mit der es mit einem der falschgeschriebenen Suchworte übereinstimmt. Stimmt das Wort überein, wird der Arrayeintrag mit der kompletten Schlagwortkette gespeichert. Nun könnte es ja möglich sein, dass ich eine Schlagwortkette mehrfach speichere, weil mehrere Suchworte Ähnlichkeiten mit mehreren Schlagworten einer Kette aufweisen. Das Array, in das ich nun die Treffer gespeichert habe, soll mir die HÄUFIGSTEN Werte NUR einmal, ABER an erster Stelle, AUSGEBEN. Jetzt vielleicht etwas klarer? Ich habe einen möglichen Lösungsansatz entwickelt, allerdings scheint der nicht zu funktionieren, wie ich es mir vorstelle: PHP-Code: Zitat:
EDIT: Ich hab jetzt eine andere Version genutzt. Mich würde aber trotzdem interessieren, wieso DAS da nicht geht? Wenn ich ein Array habe von dieser Form: $array[$n]['Wert']="Dies" $array[$n]['Zähler']=5 und ich jetzt sage, dass $n=4 ist, dann habe ich 5 Array"Fächer". Ich möchte das die Array WERTE nach den ZÄHLERN geordnet ausgegeben werden, wie realisiere ich DAS? Danke! Geändert von Sekundentakt (07.10.2008 um 19:55 Uhr) | |
| | |
| | Nach oben #7 | |||
| Johannes Schlichenmaier Registriert seit: 26.08.2005 Ort: Mannheim
Beiträge: 403
|
Hallo, sry dass ich mich jetzt erst wieder melde, aber ich hab grad recht viel um die Ohren. Zitat:
PHP interpretiert seinerseits den String, der vorher in $k[1] gespeichert war als Char-Array und da 'shortest' kein numerisches Zeichen ist, ersetzt es den ersten Charakter. Dann wird einfach $k[i] und $k['shortest'] ausgegeben. Zitat:
Beispiel 3 erklärt, wie es grundsätzlich in deinem Fall läuft. Grüße, Johannes PS: Nochmal kurz zu dem array_unique-Part da oben: array_unique() gibt dir ein Array zurück, wobei alle doppelten Einträge entfernt sind. Wenn mein Ausgangsarray so aussieht: Code: Array
(
[0] => eins
[1] => zwei
[2] => zwei
[3] => drei
[4] => vier
[5] => vier
[6] => funf
[7] => funf
)
Code: Array
(
[0] => eins
[1] => zwei
[3] => drei
[4] => vier
[6] => funf
)
So, array_diff_key() vergleicht zwei Arrays gegeneinander und gibt die Felder aus, bei denen sich keys unterscheiden. Ein PHP-Code: Die Funktion sieht also die beiden Arrays und sagt: Ok, beide Arrays haben einen Key 0, 1, 3, 4 und 6. Einen Key 2, 5 und 7 hat also lediglich das Ursprungsarray. Dies sind aber genau jenen, die die Funktion array_unique wegen doppeltem Vorkommen herausgefiltert hat. Du hast mit anderen Worten als Endergebnis die Elemente des Ursprungsarrays, die die Funktion array_unique vorher rausgelöscht hat. Die doppelten Einträge also. PPS: Falls das deine Schwierigkeit sein sollte: Wie die meisten PHP-Funktionen verändert array_unique() keine übergebenen Parameter. Nur die Rückgabe ist ein von Mehrfacheinträgen gesäubertes Array.
__________________ In the beginning was the word and the word was content-type: plain/text heute code ich, morgen debug ich und uebermorgen cast ich die koenigin auf int Geändert von Jojo (08.10.2008 um 22:01 Uhr) | |||
| | |
| | Nach oben #8 |
| Johannes Müller Registriert seit: 15.09.2005 Ort: Königreich Flieden
Beiträge: 550
|
Also mir wird letzlich nicht klar, was für einen Algorithmus du jetzt eigentlich realisieren willst... Also du hast eine Suchanfrage vom User und (aus der Datenbank) ein Reportaire verschiedener Suchvorschläge. Als Beispiel nehme ich dafür einfach mal "rote tomate", "was ganz dolles" und "telefon". Diese Vorschläge werden in einzelne Worte aufgespalten (per explode) und in einem zweidimensionalen Array gespeichert. PHP-Code: Ebenso wird auch die Suchanfrage nach Worten aufgeteilt. PHP-Code: Code: FUNCTION algo($data, $suche)
FOR $suchvorschlag IN $data
FOR $wort IN $suchvorschlag
FOR $suchwort IN $suche
IF vergleiche($suchwort, $wort)
habGefunden($suchvorschlag)
END
Die Funktion vergleiche arbeitet also mit levensthein oder was auch immer, und liefert ein ergebnis, ob die worte gleich sind oder nicht. Da könnte auch ne gewisse näherung eingebaut werden, dass auch ne 95% Übereinstimmung true zurückgibt, aber das ist jetzt grade egal. Die Funktion habGefunden sammelt alle Suchvorschläge und zählt mit, wie oft jeder gefunden wurde. In PHP könnte das so aussehen: PHP-Code: Am Ende hat man bei obigen Beispieldaten in $gefunden folgendes stehen: PHP-Code: Code: übereinstimmungen | suchvorschlag
------------------|--------------------------
2 | 2 => "was ganz dolles"
1 | 3 => "telefon"
__________________ Weißt Bescheid - Scheiß wie weit Geändert von $traight-$hoota (09.10.2008 um 00:35 Uhr) |
| | |
| | Nach oben #9 |
| neugieriger PHP-Anfäger Registriert seit: 16.08.2008 Ort: Mecklenburg-Vorpommern
Beiträge: 45
|
Hi, nein, ist es nicht. Ich bin leider von einem völlig falschen Lösungsansatz ausgegangen. Arrays sind für das, was ich möchte, völlig falsch. Ich habe mir dann tatsächlich mal das levenshtein-Funktions-Beispiel von php.net genommen und modifziert. Ich erreiche genau das, was ich vorher von euch wollte, indem ich die Treffer in eine Variable speichere. Würde ich statt einer Variable ein Array verwenden, würde das den Code am Ende aufblasen, ohne einen wirklichen Mehrwert zu bringen, da viele Arrayfelder einfach leer bleiben würden. Eine Variable reicht völlig aus, wer mehr Suchvorschläge braucht, muss das Konstrukt, wie ich, modifizieren - mit Variablen. Levenshtein-Funktion Danke aber für eure Hilfe! |
| | |
| | Nach oben #10 | |
| Johannes Schlichenmaier Registriert seit: 26.08.2005 Ort: Mannheim
Beiträge: 403
| Zitat:
Allerdings hab ich den Mund gehalten, weil mir nicht ganz klar war, wie dein Alorithmus später mal arbeiten sollte... Aber gut, dass das geklärt ist. Kannst ja, wenn du noch lustich bist, dein Endergebnis hier präsentieren. Dann haben andere vielleicht auch noch was davon... Grüße, Jojo
__________________ In the beginning was the word and the word was content-type: plain/text heute code ich, morgen debug ich und uebermorgen cast ich die koenigin auf int | |
| | |
| | Nach oben #11 |
| neugieriger PHP-Anfäger Registriert seit: 16.08.2008 Ort: Mecklenburg-Vorpommern
Beiträge: 45
|
Hier mal das, was meine Funktion macht. Ich betone, dass ich das im obrigen Link enthaltene Beispiel lediglich modifiziert habe. PHP-Code: Genau genommen, würde diese Funktion eigentlich nur zum Einsatz kommen, wenn ALLE Suchbegriffe in irgendeiner Form falsch geschrieben wurden oder absolut nicht in meiner Datenbank auftauchen. Hier das komplette Codebeispiel: PHP-Code: *Schlagworte: Schlagworte sind eigens in einer Datenbank gespeichert. Jeder Datensatz kann mehr als ein Schlagwort oder eine Schlagwortkette enthalten, diese werden, um voneinander unterschieden werden zu können, mit "||" im obrigen Beispiel getrennt. Schlagwortketten sind z.B. "Satz des Pytagoras". Sollte eine Schlagwortkette der Fall sein, zerschneide ich die Schlagwortkette. Dann vergleiche ich Wort für Wort Suchworte und Schlagwortketten. Sollte EINES von mehreren Suchworten mit EINEM Schlagwort der Schlagwortkette übereinstimmen, so wird als Suchvorschlag die ganze SCHLAGWORTKETTE ausgegeben. Anregungen: Es kam bei diesem Codeschnipsel beim Testen durchaus vor, dass ich zwei mal den Selben Suchvorschlag ausgegeben bekomme. Das liegt daran, dass, sollte ein NEUER höchster Treffer gefunden werden, der alte höchste Treffer nicht zwangsläufig nachrutscht. Wie gesagt, hierfür müsste man die Funktion erweitern, ggf. doppelte Vorschläge entfernen usw. usf. Ich muss allerdings hinzufügen, dass es mir bei Datensätzen von mehr als 100 Einträgen noch nicht vorgekommen ist, dass zwei mal der selbe Suchvorschlag auftaucht. Bei weniger Datensätzen schon eher |
| | |
| | Nach oben #12 |
| Johannes Müller Registriert seit: 15.09.2005 Ort: Königreich Flieden
Beiträge: 550
|
Ok, jetzt verstehe ich auch richtig, worum es bei dir geht^^ Ich würde dir (neben anderen Optimierungsmöglichkeiten*g*) aber trotzdem empfehlen, statt $shortest, $shortest2 und $shortest3 ein array zum abspeichern zu nehmen, da du dadurch felxibler bist und keine unnnötige Codedopplungen hast. Denn der Code für das Zuweisen und Ausgeben dieser drei variablen ist jedesmal vom Prinzip her identisch. Und wenn du dir irgendwann überlegst (warum auch immer), mehr vorschläge anbieten zu wollen, ist das durch eine einzige Variablenänderung geschehen; ebenso ist es einfacher, wenn der Code noch irgendwelche Veränderungen unterlaufen sollte (bugfixes, features...), diese nur einmal durchführen zu müssen. Du meintest in deinem vorletzten Post, dass ein Array den Code unnötig aufblasen würde: das ist falsch und genau das Gegenteil der Fall. Was durch ein Array auf den ersten Blick sein kann, ist, dass das Datenvolumen erhöht wird (bei einer großen Datenbank), aber es gibt auch Möglichkeiten, das zu verhindern. Beispielsweise musst du in $Höchster_Treffer etc. nicht den kompletten Datensatz speichern, sondern es würde reichen, eine Referenz von $words (&$words) oder einen eindeutigen Key zu übergeben (z.B. $i und ein hinzuzufügender Zähler im ersten foreach). Alternativ kann das array auch per garbage collector auf eine beliebige Anzahl der jeweils höchsten Einträge begrenzt werden.
__________________ Weißt Bescheid - Scheiß wie weit |
| | |
| | Nach oben #13 |
| neugieriger PHP-Anfäger Registriert seit: 16.08.2008 Ort: Mecklenburg-Vorpommern
Beiträge: 45
|
Könntest du den Code mal bitte dahingehend optimieren, dass das Ganze auch mit Arrays läuft? Jedesmal, wenn ich das versuche umzusetzen, zählt irgendetwas falsch hoch und er gibt das Falsche aus, bzw. auf einmal hat die längste Schlagwortkette die höchste Trefferzahl. Danke! EDIT: Ich meinte mit dem Array-Problem, dass am Ende entweder immer nur die erste Schlagwortkette des Datensatzes steht, oder auf einmal alle Schlagworte als Vorschläge in Frage kämen. |
| | |
| | Nach oben #14 |
| Johannes Müller Registriert seit: 15.09.2005 Ort: Königreich Flieden
Beiträge: 550
|
ganz am anfang müsste ein array $treffer initialisiert werden, $Höchster_Treffer, $Zweithöchster_ ... und $shortest ... entfallen. Der gesamte Abschnitt nach der levensthein-berechnung kann eigentlich entfallen; stattdessen, werden mit diesem Code, alle Ergebnisse in einer Tabelle gesammelt, mit der dann hinterher weitergearbeitet werden kann. PHP-Code: Die Ausgabe erfolgt dann so: PHP-Code: Aber das ist in der foreach-Schleife der Ausgabe relativ einfach umsetzbar.
__________________ Weißt Bescheid - Scheiß wie weit |
| | |
| | Nach oben #15 |
| neugieriger PHP-Anfäger Registriert seit: 16.08.2008 Ort: Mecklenburg-Vorpommern
Beiträge: 45
|
Ein paar Fragen zum Code: Damit deine Rechnung aufgeht, muss ich array_flip(); anwenden, da ansonsten keine $words ausgegeben werden würden, sondern Zahlenwerte, ist das richtig? Wann greift denn array_flip();, bei einer Ausgabe? Oder werden die Werte automatisch nach dem abspeichern vertauscht? Versuch bitte diese Funktion mal an diesem Beispiel etwas genauer zu erklären, dass leuchtet mir noch nicht ganz ein, wieso das so funktioniert (woher weiß array_flip(); wann "nachher" ist?). levenshtein hast du falsch verstanden, es muss nicht $treffer[$words] > $lev, sondern $treffer[$words] < $lev heißen. dein array_sclice(); ist dann glaube ich auch falsch, denn jetzt würde er zwar die ersten drei Treffer ausgeben, aber genau die sind doch die ungenauesten von allen? Du müsstest, wenn ich die Funktion richtig interpretiere, -3 angeben, damit ich die drei letzten Elemente des Arrays erhalte, da diese am genauesten sind, weil $lev am kleinsten war. Richtig? Ich könnte das was $shortest+3 gemacht hat, theoretisch auch entfallen lassen, wenn meine letzten 3 Ergebnisse vor der Ausgabe noch durch ein similar_text(); gejagt werden und ich dann nur die Werte speichere, die dem Suchstring am ähnlichsten sind. Danke für das Beispiel. |
| |