ostpower Geschrieben 18. Juni 2010 Geschrieben 18. Juni 2010 (bearbeitet) Hallo zusammen, ich möchte eine Hashtable benutzen, um Sonderzeichen zu codieren. Das sieht dann so ungefähr aus: Hashtable h = new Hashtable(); h.put("!","!"); h.put(""","""); //<-Problem h.put("#","#"); h.put(".\",".\"); //<-Problem Jetzt gibt es aber ein Problem mit dem Anführungszeichen ". Die Werte werden ja in "" geschrieben, wenn ich jetzt aber selber ein " dort reinschreiben will geht das nicht. Wie kann ich das lösen? Das Gleiche gilt für \ Das darf ich auch nicht eingeben. vg Bearbeitet 18. Juni 2010 von ostpower Zitieren
El Ninjo Geschrieben 18. Juni 2010 Geschrieben 18. Juni 2010 Das sollte mit Escape-Sequenzen klappen. Zitieren
Dragon8 Geschrieben 18. Juni 2010 Geschrieben 18. Juni 2010 In dem du diese Zeichen einfach mit einem Backslash ( \ ) maskierst. Siehe: Galileo Computing :: Java ist auch eine Insel (8. Auflage) – 2.3 Datentypen, Typisierung, Variablen und Zuweisungen Bei Escape-Sequenzen Zitieren
flashpixx Geschrieben 18. Juni 2010 Geschrieben 18. Juni 2010 Du musst Sonderzeichen wie " oder \ maskieren. Zusätzlich solltest Du Deine Hashtable mit passenden Typen versehen. Hashtable ist eine generische Datenstruktur, da Du mit Strings arbeitest, solltest bei der Deklaration und dem Konstruktoraufruf auch die passenden Typen mitgeben Zitieren
ostpower Geschrieben 21. Juni 2010 Autor Geschrieben 21. Juni 2010 Du musst Sonderzeichen wie " oder \ maskieren. Zusätzlich solltest Du Deine Hashtable mit passenden Typen versehen. Hashtable ist eine generische Datenstruktur, da Du mit Strings arbeitest, solltest bei der Deklaration und dem Konstruktoraufruf auch die passenden Typen mitgeben Wie meinst du das? Wo soll ich den Typ mitgeben? Kannst du ein Beispiel nennen/schreiben? Zitieren
lupo49 Geschrieben 21. Juni 2010 Geschrieben 21. Juni 2010 Wie meinst du das? Wo soll ich den Typ mitgeben? Kannst du ein Beispiel nennen/schreiben? Bei generischen Datentypen gibt man normalerweise den Datentyp mit an, der dort gespeichert werden soll. Hashtable<String, String> h = new Hashtable<String, String>(); Bei deiner Deklaration lässt sich alles mögliche in die Map schreiben, z.B. auch eine Key-Schlüssel-Kombination aus Integers und irgendwelchen Objects. Galileo Computing :: Java ist auch eine Insel (8. Auflage) – 9 Generics, innere Klassen Zitieren
ostpower Geschrieben 22. Juni 2010 Autor Geschrieben 22. Juni 2010 Ok, ich habe eine weitere Frage bzgl. der Schachtelung. Ich wollte mit zuerst mit einer for-schleife die einzelnen Zeichen durchlaufen und dann in einer weiteren schleife die hashtable durchlaufen, und dadurch das zeichen mit der hashtable abgleichen, aber das klappt nicht so recht: for(int i=0; i<eingabe.length();i++){ while(e.hasMoreElements()){ Object hash = e.nextElement(); Object zeichen = eingabe.charAt(i); if(zeichen == hash){ System.out.println("treffer"); } else{ System.out.println("ok"); } break; } } Wenn ich das so mache, dann nimmt er nur das erste zeichen, vergleicht es mit allen hash-werten gibt den status "ok" für jeden hashwert aus. Bei der eingabe von "Ein < Test" möchte ich aber sowas kriegen: ok ok ok ok treffer ok ok ok ok ok Wie mach ich das? Zitieren
Klotzkopp Geschrieben 22. Juni 2010 Geschrieben 22. Juni 2010 Ich wollte mit zuerst mit einer for-schleife die einzelnen Zeichen durchlaufen und dann in einer weiteren schleife die hashtable durchlaufenMan "durchläuft" keine Hashtabelle, das widerspricht dem ganzen Konzept. Man benutzt Hashtabellen ja gerade deshalb, weil man sich das Durchlaufen ersparen möchte. Wenn du sowieso nur sequenziell durch die Einträge hechelst, brauchst du keine Hashtabelle, da tut's auch eine unsortierte Liste. Schau dir mal die Methode containsKey an. Zitieren
ostpower Geschrieben 22. Juni 2010 Autor Geschrieben 22. Juni 2010 Man "durchläuft" keine Hashtabelle, das widerspricht dem ganzen Konzept. Man benutzt Hashtabellen ja gerade deshalb, weil man sich das Durchlaufen ersparen möchte. Wenn du sowieso nur sequenziell durch die Einträge hechelst, brauchst du keine Hashtabelle, da tut's auch eine unsortierte Liste. Schau dir mal die Methode containsKey an. nee ich wills ja mit ner Hashtable machen. Aber wie mach ich das dann, dass er den String mit der Hashtable abgleicht? Zitieren
Dragon8 Geschrieben 22. Juni 2010 Geschrieben 22. Juni 2010 nee ich wills ja mit ner Hashtable machen. Aber wie mach ich das dann, dass er den String mit der Hashtable abgleicht? Und jetzt liest du dir nochmal einmal GENAU durch was Klotzkopp dir dazu geschrieben hast, und schreist nicht einfach "nee". Vor allem seinen letzten Satz solltest du dir mal zu Gemüte führen, weil das quasi schon deine Lösung ist. Außerdem scheinst du dich mit den Generics auch noch nicht beschäftigt zu haben, oder benutzt du eine Java Version < 1.5? Zitieren
ostpower Geschrieben 22. Juni 2010 Autor Geschrieben 22. Juni 2010 Man "durchläuft" keine Hashtabelle, das widerspricht dem ganzen Konzept. Man benutzt Hashtabellen ja gerade deshalb, weil man sich das Durchlaufen ersparen möchte. Wenn du sowieso nur sequenziell durch die Einträge hechelst, brauchst du keine Hashtabelle, da tut's auch eine unsortierte Liste. Schau dir mal die Methode containsKey an. ContainsKey würde eigentlich gut passen, nur erwartet er einen String, da die einzelnen Zeichen des Strings aber vom Typ char sind, geht das so nicht. Ein Cast von char zu String gehta auch nicht. for(int i=0; i<eingabe.length();i++){ if(h.containsKey(eingabe.charAt(i))){ System.out.println("Treffer" + eingabe.charAt(i)); } else{ System.out.println("Kein Treffer"); } } Zitieren
ostpower Geschrieben 22. Juni 2010 Autor Geschrieben 22. Juni 2010 ContainsKey würde eigentlich gut passen, nur erwartet er einen String, da die einzelnen Zeichen des Strings aber vom Typ char sind, geht das so nicht. Ein Cast von char zu String gehta auch nicht. for(int i=0; i<eingabe.length();i++){ if(h.containsKey(eingabe.charAt(i))){ System.out.println("Treffer" + eingabe.charAt(i)); } else{ System.out.println("Kein Treffer"); } } Hat sich erstmal erledigt. Es klappt jetzt. Zitieren
Dragon8 Geschrieben 22. Juni 2010 Geschrieben 22. Juni 2010 Ein Cast von char zu String gehta auch nicht. String (Java Platform SE 6) Ansonsten wäre es nett für andere Leute die vielleicht ein ähnliches Problem haben, dein Lösung zu posten. Zitieren
ostpower Geschrieben 22. Juni 2010 Autor Geschrieben 22. Juni 2010 String (Java Platform SE 6) Ansonsten wäre es nett für andere Leute die vielleicht ein ähnliches Problem haben, dein Lösung zu posten. Ja ganz ruhisch, hätte ich noch gepostet, da ich mit gesamten Thema eh noch nicht fertig bin. Also es lag an den Typen der Hastable, wenn man ein Wert als Character angibt klappt es. Hashtable<Character, String> h = new Hashtable<Character, String>(); Ich hab jetzt allerdings ein neues Problem. Ich habe nicht nur einzelne Zeichen in der Hashtable stehen sonder auch mehrere, z.B. "./" Jetzt kann ich nicht mehr den eingabe-string zeichenweise durchlaufen, weil er ja dann . und / überprüft aber nicht ./ Ich müsste also den String nicht nach einem Zeichen sondern einer Zeichenkette durchsuchen. Es gibt zwar die String-Methode contains, aber das klappt nicht so recht. Zitieren
flashpixx Geschrieben 22. Juni 2010 Geschrieben 22. Juni 2010 Hashtable<Character, String> h = new Hashtable<Character, String>(); Das bedeutet, dass Du genau einen Character als Hashschlüssel verwendest Ich müsste also den String nicht nach einem Zeichen sondern einer Zeichenkette durchsuchen. Es gibt zwar die String-Methode contains, aber das klappt nicht so recht. Doch, es ist genau das was die Definition einer Hashtabelle ist. Du hast einen Schlüssel und ordnest diesem Schlüssel einen Wert zu. Bei Dir ist der Schlüssel ein einzelner Character. Ein Hashtabelle ist dafür gedacht um möglichst effizient abhängig von einem Wert ein Element wieder zu finden, ohne dass man aufwendig durchsuchen muss. Also entweder benutzt Du mehrere Hashwerte, wobei ich dann zu Strings und nicht zu Charactern raten würde, in Du dann eben alle Deine Schlüssel einfügst oder Du musst Dir Gedanken über eine andere Datenstruktur machen Zitieren
ostpower Geschrieben 23. Juni 2010 Autor Geschrieben 23. Juni 2010 Das bedeutet, dass Du genau einen Character als Hashschlüssel verwendest Doch, es ist genau das was die Definition einer Hashtabelle ist. Du hast einen Schlüssel und ordnest diesem Schlüssel einen Wert zu. Bei Dir ist der Schlüssel ein einzelner Character. Ein Hashtabelle ist dafür gedacht um möglichst effizient abhängig von einem Wert ein Element wieder zu finden, ohne dass man aufwendig durchsuchen muss. Also entweder benutzt Du mehrere Hashwerte, wobei ich dann zu Strings und nicht zu Charactern raten würde, in Du dann eben alle Deine Schlüssel einfügst oder Du musst Dir Gedanken über eine andere Datenstruktur machen Also die Dekleration meiner Hashtable lautet jetzt Hashtable<String, String> h = new Hashtable<String, String>(); Denn ich habe auch als Key mehrere Zeichen wie z.B. "./" Ich komme allerdings nicht darauf wie ich das abprüfen kann. Kann mir jemand mal ein Codebeispiel geben, wie ich einen Eingabe-String überprüfe, und dabei alle Zeichen bzw. Zeichenketten innerhalb des Eingabe-Strings, die in der Hashtable stehen, austausche? Zitieren
Klotzkopp Geschrieben 23. Juni 2010 Geschrieben 23. Juni 2010 Denn ich habe auch als Key mehrere Zeichen wie z.B. "./"Wie lang können die Keys denn werden? Passiert mit einem einzelnen Punkt oder Slash etwas anderes als mit dieser Kombination? Du kannst jeden Substring der zu prüfenden Zeichenkette, eben bis zur maximalen Länge der Keys, gegen die Hashtable prüfen. Dazu brauchst du zwei verschachtelte Schleifen, eine für die Startposition und eine für die Länge des Substrings. Wenn es viele Einzelzeichen-Keys und nur wenige Zeichenketten-Keys gibt, könntest du die Einzelzeichen mit einer Hashtable verarbeiten und die längeren mit einer Liste und Suchen&Ersetzen. Dabei musst du aber penibel darauf achten, dass nicht bereits ersetzte Zeichen nochmals verarbeitet werden. Zitieren
flashpixx Geschrieben 23. Juni 2010 Geschrieben 23. Juni 2010 Ich komme allerdings nicht darauf wie ich das abprüfen kann. Kann mir jemand mal ein Codebeispiel geben, wie ich einen Eingabe-String überprüfe, und dabei alle Zeichen bzw. Zeichenketten innerhalb des Eingabe-Strings, die in der Hashtable stehen, austausche? Im Pseudocode string newstring = "" for(int i=0; i < mystring.length; ++i) if (hashtable.contains(mystring.charat(i)) newstring += hashtable.getvalue(mystring.charat(i)) else newstring += mystring.char.charat(i); @Klotzkopp: Im Grunde geht das auch mit einer Hashtable, wobei man dann eben aus dem String, den man ersetzen will, eben via "substr" immer Zeichenketten ausschneidet und die auch als Keys in der Hashtable gespeichert sind. Letztendlich würde ich mir aber da eher die Gedanken machen, wie viele Elemente in der Hashtabelle sein müssen und wie lang maximal die Substrings sein können, denn man hätte ja dann immer grob: for (length of string) for (max length of substring) Wobei das grob abgeschätzt O(n^2) [sofern die Länge des Substrings = Länge des Strings wird] + die Suche in der Hashtabelle ist. Das wäre sicherlich nicht sehr effizient. Ich denke auch der Vorschlag mit einer iterativen Nachbearbeitung wird knapp unterhalb von O(n^2) liegen. Wenn es um sehr viele Ersetzungen geht würde ich über eine String-Alignment Algorithmen das machen (Sequenzalignment ? Wikipedia), um heraus zu bekommen, was überhaupt ersetzt werden muss und dann würden sich wohl http://de.wikipedia.org/wiki/String-Matching-Algorithmen anbieten Zitieren
ostpower Geschrieben 23. Juni 2010 Autor Geschrieben 23. Juni 2010 Also die Hashtable hat 10 Einträge: h.put("!" , "!"); h.put("\"","""); h.put("#","#"); h.put("$","$"); h.put("%","%"); h.put("*","*"); h.put("+","+"); h.put("--","--"); h.put("./","./"); h.put("\\R","\R"); Drei von den Werten bestehen also aus mehr als einem Zeichen. Was wäre da jetzt die effektivste Lösung? Mit charAt kann ich ja nicht arbeiten, da bei dem String "Ein -- Test" nur das "-" geprüft werden würde, nicht aber "--" Zitieren
flashpixx Geschrieben 23. Juni 2010 Geschrieben 23. Juni 2010 Drei von den Werten bestehen also aus mehr als einem Zeichen. Was wäre da jetzt die effektivste Lösung? Mit charAt kann ich ja nicht arbeiten, da bei dem String "Ein -- Test" nur das "-" geprüft werden würde, nicht aber "--" Du musst jedes Zeichen und eben immer zwei Zeichen prüfen, wie schon gesagt die Stringklasse von Java bietet substring an. Am sinnvollsten prüfst Du erst die längsten String und dann immer zum kürzesten. Pseudocode for(i=0; i < mystr.length-1; ++i) if hashmap.contains(mystr.substr(i,i+1)) newstr += hashmap.getvalue(mystr.substr(i,i+1)) else if hashmap.contains(mystr.charat(i)) newstr += hashmap.getvalue(mystr.charat(i)) else newstr += mystr.charat(i) if hashmap.contains(mystr.charat(mystr.length-1)) newstr += hashmap.getvalue(mystr.charat(mystr.length-1)) else newstr += mystr.charat(mystr.length-1) Zitieren
blue rabbit Geschrieben 24. Juni 2010 Geschrieben 24. Juni 2010 Also die Hashtable hat 10 Einträge: [...] Drei von den Werten bestehen also aus mehr als einem Zeichen. Was wäre da jetzt die effektivste Lösung? Mit charAt kann ich ja nicht arbeiten, da bei dem String "Ein -- Test" nur das "-" geprüft werden würde, nicht aber "--" Ohne wirklich dein Problem, bzw. Lösung zu verstehen, schau mal hier: Pattern (Java 2 Platform SE v1.4.2) Zitieren
blue rabbit Geschrieben 24. Juni 2010 Geschrieben 24. Juni 2010 @ostpower noch ein Tip: Bevor man eine Hashtable nach keys durchsucht sollte man sich überlegen ob es bessere Ansätze gibt. Wenn es bei dir um suchen/ersetzen innerhalb eines Strings gehen sollte, wirst du dich mit regulären Ausdrücke beschäftigen müssen, sofern du eine effektive und effiziente Lösung anstrebst. Beim Zusammensetzen von (vielen) Strings kann man auch StringBuilder oder die "threadsafe version" StringBuffer verwenden. Zitieren
Empfohlene Beiträge
Dein Kommentar
Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.