Autor Beitrag
Johannes Maier
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 173

Win XP
D7 Prof
BeitragVerfasst: Di 07.12.04 19:50 
Hi,

ich hab da ein Problem (logisch, sonst würd ich ja nicht posten...): Gibt es eine Möglichkeit, so etwas wie ein Set of String zu deklarieren?
Ich habe bestimmte Befehlswörter in einer Tabelle und möchte diese nun in ein Array schreiben, allerdings möchte ich da nicht schreiben:
ausblenden Delphi-Quelltext
1:
if sString = 'DEF' or sString = 'ADD' or ...... etc.					

sondern eher so:
ausblenden Delphi-Quelltext
1:
if sString in Befehle then .....					


Aber man kann ja kein Set of String deklarieren, so wie ich das sehe? Wie bekomme ich das hin, eine Menge dieser Befehle (Strings) zu erstellen um dann eine "in"-Abfrage zu machen?

Danke,
Johannes

_________________
MfG
Johannes ehem. jbmaier
Pille
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 105

Windows 7
DelphiXE Prof.
BeitragVerfasst: Di 07.12.04 20:11 
TStringList verwenden, da gibt es die Methode Find.

Pille
Johannes Maier Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 173

Win XP
D7 Prof
BeitragVerfasst: Di 07.12.04 20:15 
TStringList kenne ich, aber kann ich da den in-Operator drauf verwenden? Das mit dem Find ist denke ich immer noch etwas umständlicher als das mit in ;)
Ich brauche das ja nur für die Abfrage, damit die kurz gehalten werden kann.

_________________
MfG
Johannes ehem. jbmaier
Pille
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 105

Windows 7
DelphiXE Prof.
BeitragVerfasst: Di 07.12.04 20:22 
Warum kannst du nicht schreiben

ausblenden Delphi-Quelltext
1:
if Befehle.Find(sString,position) then					


das entspricht doch in etwa

ausblenden Delphi-Quelltext
1:
if sString in Befehle then .....					


Ich finde das eigentlich nicht aufwändiger.

Pille
Johannes Maier Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 173

Win XP
D7 Prof
BeitragVerfasst: Di 07.12.04 20:34 
Ok danke, dann werd ich das so machen :D

_________________
MfG
Johannes ehem. jbmaier


Zuletzt bearbeitet von Johannes Maier am Di 07.12.04 21:18, insgesamt 1-mal bearbeitet
IngoD7
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 629


D7
BeitragVerfasst: Di 07.12.04 20:55 
Denke daran, dass Find nur bei sortierten Listen funktioniert. Ansonsten, wie bei DP vorgeschlagen: IndexOf

((Ich mag irgendwie keine Cross-Postings))
retnyg
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 2754

SNES, GB, GBA, CPC, A500, 486/66, P4/3.0HT: NintendOS, AmigaOS, DoS
Delphi 5, Delphi 7
BeitragVerfasst: Mi 02.03.05 16:41 
gibts da nicht noch ne elegantere möglichkeit zu prüfen ob ein string in einer menge vorkommt ?
am besten etwas was man als konstante deklarieren kann.
ich hab sowas schon gesehen, weiss nur nicht mehr wie es genau ging
delfiphan
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2684
Erhaltene Danke: 32



BeitragVerfasst: Mi 02.03.05 18:32 
Das normale "set of" kann halt vom Compiler komfortabel in Bitoperationen umgewandelt werden. Bei einem "set of byte" muss der Compiler schon mit 256 Bits / 32 Bytes hantieren.
Set of String jedoch wäre von der Art her noch viel komplizierter, es würde einfach drauf hinauslaufen eine Liste mit Strings zu haben und diese zu durchsuchen. Deswegen muss man es selbst programmieren. Für eine schnelle Suche von vielen Strings gibt es sog. Hashfunktionen (such mal im Google oder Forum); die wandeln dir nen String in eine Zahl um (das ist dann natürlich nicht eindeutig möglich).
Tipp: Wenn du die Strings alle in einer sortierten Liste/Array hast, ist die Suche besonders einfach (siehe Binary Search).
retnyg
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 2754

SNES, GB, GBA, CPC, A500, 486/66, P4/3.0HT: NintendOS, AmigaOS, DoS
Delphi 5, Delphi 7
BeitragVerfasst: Do 03.03.05 00:54 
na gut; der letzte ansatz den ich gewählt habe war dieser:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
const 
  glyphnames = 'play#pause#stop#back#fwd#mini_miniz#mini_switch#mini_close#';

begin
      s:=glyphnames;
      for i := 1 to 8 do begin
        s2:=copy(s,1,pos('#',s)-1);
        s :=copy(s,pos('#',s)+1,length(s));
        case i of
          1..5 : bla(s2);
          6..8: blubb(s2);
        end;
      end;
end;

wem fällt ne bessere lösung dazu ein ? (voraussetzung: muss als konstante hinterlegt werden können ohne da lange erst zur laufzeit ne stringlist zu erstellen und da die werte reinkopieren, dasselbe gilt für nen array)
bei der variante hier liesse sich mit pos prüfen ob ein string in der liste enthalten ist.
delfiphan
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2684
Erhaltene Danke: 32



BeitragVerfasst: Do 03.03.05 01:17 
@retnyg: Zur Laufzeit reinkopieren? Das wäre ja bei einem Array nicht nötig..
=> Strings sortiert als Array speichern + binäre Suche:
ausblenden Delphi-Quelltext
1:
2:
const
 StrArray : array[1..3of String = ('alphorn','brieftasche','cervelat');
delfiphan
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2684
Erhaltene Danke: 32



BeitragVerfasst: Do 03.03.05 01:30 
@Johannes Maier: Mal ne Frage: Wieviele Befehle gibt es denn? Muss die Liste erweiterbar sein? Kannst du die Befehle mal posten?
Man könnte eventuell etwas recht Simples mit einer trivialen Hashfunktion basteln, wenn es denn nur wenige Befehle sind.

Übrigens: Könntest du nochmals kurz erklären, was du genau tun willst? Willst du einfach überprüfen können ob ein gegebener String eines deiner Befehle entspricht? D.h. ein "function isCommand(S : String) : Boolean" ? Hab ich das richtig verstanden?


Zuletzt bearbeitet von delfiphan am Do 03.03.05 01:38, insgesamt 1-mal bearbeitet
retnyg
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 2754

SNES, GB, GBA, CPC, A500, 486/66, P4/3.0HT: NintendOS, AmigaOS, DoS
Delphi 5, Delphi 7
BeitragVerfasst: Do 03.03.05 01:36 
johannesmaiers problem ist schon lange gelöst, ich habe den alten post nur nochmal aufgewärmt da mich das zur zeit beschäftigt. wäre nett wenn du das mit der binären suche oder dem hashwert mal kurz anreissen könntest damit ich ne ahnung bekomme an was du dabei denkst.
delfiphan
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2684
Erhaltene Danke: 32



BeitragVerfasst: Do 03.03.05 01:44 
Lol 13.4.2004. Sorry, hab's nicht gesehn ;)
Eine Hashfunktion ist eine Funktion, die aus einem langen String eine Zahl bastelt. Du kannst damit eine Suche sehr schnell einschränken. Eine etwas blöde Hashfunktion gibt z.B. einfach den ersten Buchstaben des Strings zurück. Eine gute Hashfunktion berücksichtigt alle Zeichen und verhindert möglichst Kollisionen mit anderen Strings.
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
var I : Integer;
// ...
I := HashFunc('Hallo'); // I ist 123
Case I of
 123: ShowMessage('Das Wort ist "Hallo"');
 412: ShowMessage('Das Wort ist "Welt"');
 921: ShowMessage('Das Wort ist "Delphi"');
 222: ShowMessage('Kollision von zwei Wörtern: Das Wort ist entweder "Windows" oder "Absturz"'); // => weiterer Vergleich nötig
 //...
end;
// Die Funktion HashFunc gibt's natürlich im Delphi nicht. Das ist hier nur so schematisch dargestellt, was das ganze bringt.

Eine binäre Suche kannst du in einem sortierten Array durchführen.
Das ist das, was du machst, wenn du ein Wort im Duden nachschaust: Du schlägst den Duden einfach mal in der Hälfte auf, und entscheidest dann, ob sich das gesuchte Wort in der ersten oder zweiten Hälfte des Dudens befindet. Wenn du merkst, dass sich das Wort in der ersten Hälfte befindet, dann machst du dasselbe wieder mit dieser Hälfte, usw. bis du eben am Ziel bist... Wenn du 4 Millarden Wörter hast, hast du nach spätestens 32 Male Blättern das Wort gefunden.
(Hoffentlich war das in etwa verständlich)
retnyg
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 2754

SNES, GB, GBA, CPC, A500, 486/66, P4/3.0HT: NintendOS, AmigaOS, DoS
Delphi 5, Delphi 7
BeitragVerfasst: Do 03.03.05 01:59 
hmmm... also das mit der hashfunc erfordert dass ich jeden string einzeln einer zahl zuweise. was das ganze sicher nicht viel einfacher macht (ausser dass ich mit case drauf zugreifen kann)
den theoretischen teil der binären suche habe ich auch gerafft; wo liegt aber jetzt in der praxis der vorteil dran ob ich
 if pos(kommando, kommandoliste) > 0 thenoder
 if pos(kommando, copy(kommandoliste,1,length(kommandoliste) div 2)) > 0 then mache ?
die 2te variante ist wahrscheinlich noch ein stück langsamer da der string erst zerteilt werden muss.
delfiphan
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2684
Erhaltene Danke: 32



BeitragVerfasst: Do 03.03.05 02:07 
Nee, du musst nicht jedem String eine Zahl zuweisen. MD5 ist z.B. eine Hashfunktion. Oder die CRC checksumme. Eine einfache Summe aller Chars wäre eine Hashfunktion. Alle Chars zusammen ge-xor-t ist eine Hashfunktion. Man kann da vieles mal ausprobieren. Man muss schlussendlich eine wählen, wo es möglichst keine Kollisionen gibt.

Pos durchsucht den String von Anfang bis Schluss und geht einfach linear durch. Wenn die Liste doppelt so lang ist, hat Pos auch doppelt so lange. Der Aufwand ist linear, oder "O(n)". Bei einer binären Suche ist der Aufwand bloss "O(log(n))".
Mit anderen Worten: In der gleichen Zeit, die Pos braucht, um 32 Strings zu durchsuchen, hat die Binäre Suche schon 4 Milliarden Strings durchsucht (Wieso? Um beim Dudenbeispiel zu bleiben: Wenn du den Duden einfach mal in der Hälfte aufschlägst und merkst, dass das gesuchte Wort in der ersten Hälfte ist, dann musst du die zweite Hälfte des Dudens gar nicht berücksichtigen. Du kannst also die Hälfte des Dudens sofort ausschliessen. Du schaust dir die Hälfte aller Wörter gar nicht an. Bei einer linearen Suche gehst du alle Wörter einzeln durch.) Bei einer binären Suche musst du aber ein sortiertes Array haben!

So, bin raus für heute. *weg


Zuletzt bearbeitet von delfiphan am Do 03.03.05 02:12, insgesamt 1-mal bearbeitet
retnyg
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 2754

SNES, GB, GBA, CPC, A500, 486/66, P4/3.0HT: NintendOS, AmigaOS, DoS
Delphi 5, Delphi 7
BeitragVerfasst: Do 03.03.05 02:11 
danke für deine tipps, werde drüber noch eingehend meditieren...

gn8