Seite 1 von 1

[solved] QMap mit teilkey durchsuchen

Verfasst: 18. September 2013 13:18
von Abayo
Hiho @ all!

Ich habe folgendes Problem:

Für ein Adressbuch program habe ich eine QMap erstellt welche eine Person-Klasse als value und den Namen (Name, Vorname) als Key beeinhaltet.
Nun möchte ich eine Suchfunktion einbauen der nur ein Teil des Namens reicht. Z.B. wenn ein Kontakt "Cruise, Tom" und ein 2ter Kontakt "Der Frosch, Kermit" heißt, mir aber nur "Tom" oder "Kermit" oder "Cruise" einfällt, dann soll mit diesen einzelnen Wörtern ein od. mehrere Treffer gefunden werden (z.B. wenn 3 Kontakte den Nachnamen "Crusie" haben).
Ob ich diese dann anzeige weiß ich noch nicht, es geht mir erstmal nur um das finden.

Ich habe schon ein wenig mit QMap und dem Iterator getestet, aber diese brauchen immer den vollen Namen/den vollen key.
Was könnte ich da machen? Geht das überhaupt?

Re: QMap mit teilkey durchsuchen

Verfasst: 25. September 2013 09:28
von Hulk2442
Hi
Ich glaube nicht das das mit einer QMap so gut funken wird.
Einfach aus dem Grund das die Key's innerhalb einer QMap automatisch einen Hashwert bekommen damit du schnell die Daten abfragen kannst.
Wenn du jetzt nur einen Teil-Key hast wirst du nie einen vollen Hashwert daraus errechnen können.

Was du machen könntest ist einerseits mit einem QMapIterator die Map durchgehen und so jeden einzelnen Key abfragen ob dieser mit den eingegebenen Daten übereinstimmt

Code: Alles auswählen

QString sEntry = "ASDF";
QMapIterator<QString, int> it(map);
while( it.hasNext() )
{
	if( it.key.contains( sEntry )  )
	{
		//do something with it.value()
	}
	else
	{}	// do nothing //
}
Jedoch musst du dabei mindestens einmal die komplette Map durchlaufen.

Was sich meiner Meinung nach besser eignen würde ist wenn du eine SQLite Datenbank für dein Vorhaben verwenden würdest.
Diese ist leicht zu handhaben und du kannst diese aus Qt heraus erzeugen als auch den Inhalt mit einem "query" abfragen.
http://www.techonthenet.com/sql/like.php

Re: QMap mit teilkey durchsuchen

Verfasst: 25. September 2013 11:49
von Abayo
Hi Hulk

die Lösung mit contains bezieht sich aber trotzdem darauf dass der gesamte key vorhanden ist, oder?

Das mit der SQLite Datenbank ist ein guter Tipp. Das werd ich mir mal später reinziehen, aber für das kleine Projekt ist es glaub ich ein wenig zuviel XD
Falls ich das größer ausbauen werd, werd ich mich darauf beziehen, aber im moment werd ich dann wohl erstmal bei dem gesamten key bleiben.

Andere Frage: der Link bezieht sich auf ein SQL like und kein SQLite -> einfach eine namensspielerei von einem anderen anbieter oder gibt es da Unterschiede?

Re: QMap mit teilkey durchsuchen

Verfasst: 26. September 2013 14:01
von hilefoks
Abayo hat geschrieben:die Lösung mit contains bezieht sich aber trotzdem darauf dass der gesamte key vorhanden ist, oder?
Nein, er fragt hier ob der Key das gesuchte Teilwort enthält, nicht die ganze Map.
Abayo hat geschrieben:Andere Frage: der Link bezieht sich auf ein SQL like und kein SQLite -> einfach eine namensspielerei von einem anderen anbieter oder gibt es da Unterschiede?
Nein. SQLite ist ein recht einfaches, eingebettetes Datenbanksystem (man braucht also keinen extra Datenbank-Server aufsetzen). Siehe auch Wikipedia dazu. Andere bekannte System sind z.B. MySQL, PostgreSQL, Oracle Database oder Microsoft SQL Server. Aber es gibt da auch noch viele andere...

SQL selbst ist die Sprache der Datenbanken. Siehe ebenfalls Wikipedia dazu. Das von Hulk2442 angesprochende SQL like bezieht sich auf einen solchen SQL Befehl (eben LIKE), mit dem man Datensätze aus der Datenbank anhand von Ähnlichkeiten/Teilwörtern 'filtern' kann.

Beispiel: Du hättest eine Tabelle Personen mit den Spalten Vorname und Nachname, wobei folgende Personen darin gespeichert sind:
Maike Müller
Wolfgang Maximus
Max Schleier

Mit dem SQL Befehl:

Code: Alles auswählen

SELECT * FROM Personen WHERE Nachname LIKE 'M%';
würdest du Maike Müller und Wolfgang Maximus als Ergebnis erhalten. Das % Zeichen steht in der Abfrage also für 'beliebiges Zeichen'. Bei der Abfrage

Code: Alles auswählen

SELECT * FROM Personen WHERE Nachname LIKE '%er';
würdest du hingegen Maike Müller und Max Schleier erhalten, da beide auf 'er' enden.

Aber nun gut - SQL ist vielleicht auch erstmal zu viel. Nix für ungut. ;-)

MfG,
Hilefoks

Re: QMap mit teilkey durchsuchen

Verfasst: 30. September 2013 09:27
von Hulk2442
Der Aufbau einer Map sieht wie folgt aus

Code: Alles auswählen

HASH	|	Key		Value
-------+----------------------------
0234	|	Maier    0048 123 456789
1024	|	Franz    0049 123 456798
2489	|	Huber    0050 123 456789
5689	|	Karl     0051 123 456798
Dabei wird der HASH anhand des eingetragenen Keys generiert.
Das bedeutet das "Maier" immer "0234" ergibt.
Lässt du nun ein Zeichen aus oder fügst eines hinzu erhältst du einen anderen HASH-Wert.

Der Zugriff auf die Daten erfolgt grobgesagt in dieser Reihnfolge:
1.) Berechnung des HASH-Wertes aus dem zu suchenden Key
2.) Suchen des Eintrages in der Map mit dem berechneten Hash-Wert
3.) Rückgabe des gefundenen Eintrages

Es ist nicht möglich einen Teil-Hash-Wert aus einem Teil-Key zu berechnen da es sowas wie einen Teil-Hash-Werte nicht gibt!

Wie "hilefoks" bereits schreibt ist SQL genauso wie C++ eine Sprache und "SELECT, FROM, LIKE, usw." sind einfach die Befehle innerhalb dieser Sprache.

"SQLITE" ist ein Datebanktyp welcher die SQL Befehle benutzt um auf die Daten zuzugreifen.

Wen du keine Datenbank benutzen willst kannst du wie bereits erwähnt den Code vom ersten Posting verwenden.
Das einzige was ich dir dabei empfehlen würde ist das du alle gefundenen Einträge in einen eigenen dynamischen Vektor ablegst und dann diesen durchsuchst und dessen Ergebnisse wieder separat ablegst und den durchsuchst usw. .

Bsp.:
Aus 100 Einträgen findest du 40 passende
Aus 40 Einträgen findest du 15 passende
Aus 15 Einträgen findest du 3 passende
Aus 3 Einträgen findest du den was du suchst.

Somit musst du nicht jedes mal alles durchsuchen, sondern nur einen Teil.

Re: QMap mit teilkey durchsuchen

Verfasst: 30. September 2013 13:10
von Abayo
OK, danke für die ausführlichen Antworten :)
Damit sind erstmal alle Fragen dafür beantwortet :D