PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Doppelte Zeichen ersetzen


DrWhiteLetter
10.01.2008, 17:32
Hi,

ich würde gerne einen String auf doppelte Zeichen prüfen und dann das doppelte Zeichen entfernen, so dass jedes Zeichen nur 1x vorhanden ist.

Beispiel:
"hallo ludo" wird zu "halo ud"

Ich hab leider nicht mal einen Ansatz, das zu realisieren, evt. ist es ja gar nicht möglich und ich muss das doch mit Perl manuell machen.

Danke schon mal für eure Hilfestellung.


Firefall
10.01.2008, 18:07
Hi,

ich würde gerne einen String auf doppelte Zeichen prüfen und dann das doppelte Zeichen entfernen, so dass jedes Zeichen nur 1x vorhanden ist.

Beispiel:
"hallo ludo" wird zu "halo ud"

Ich hab leider nicht mal einen Ansatz, das zu realisieren, evt. ist es ja gar nicht möglich und ich muss das doch mit Perl manuell machen.

Danke schon mal für eure Hilfestellung.
Hmm... Könnte schwierig werden. Selber programmieren ist viel einfacher hier! Du hast 3 Strings, String 1, 2 und 3.
String 1 ist dein Text. Den gehst du Zeichen für Zeichen durch. Wenn das aktuelle Zeichen in String 2 vorhanden ist, dann gehst du zum nächsten. Wenn nicht, dann hängst du es an an String 2 und 3 an. String 3 ist dein Ergebnis. Sollte mit <10 Zeilen Code machbar sein.

DrWhiteLetter
10.01.2008, 18:34
Das zu programmieren sollte nicht das Problem sein, aber falls es halt doch eine Möglichkeit via RegEx gibt, fände ich diese wesentlich schöner (und kürzer ;) ).

Danke aber trotzdem für die Mühe.

Firefall
10.01.2008, 19:40
Das zu programmieren sollte nicht das Problem sein, aber falls es halt doch eine Möglichkeit via RegEx gibt, fände ich diese wesentlich schöner (und kürzer ;) ). Mit RegExp dürfte es in jedem Fall weniger effizient sein, falls es geht. Der Ausdruck, der mir einfällt, ist weit über 1000 Zeichen lang und dürfte schwerer verständlich sein als ein Code der Art wie ich ihn beschrieben habe.

eViL_oNe
10.01.2008, 23:46
Hmm... Könnte schwierig werden. Selber programmieren ist viel einfacher hier! Du hast 3 Strings, String 1, 2 und 3.
String 1 ist dein Text. Den gehst du Zeichen für Zeichen durch. Wenn das aktuelle Zeichen in String 2 vorhanden ist, dann gehst du zum nächsten. Wenn nicht, dann hängst du es an an String 2 und 3 an. String 3 ist dein Ergebnis. Sollte mit <10 Zeilen Code machbar sein.

geht sogar noch etwas effizienter:

man nehme einen beliebigen assoziativen Container in der Progsprache der Wahl (auch Hashtabelle genannt). In die speichert man jedes Zeichen der Eingabe, das dort nicht vorhanden ist ein. Sollte das Zeichen schon im Container sein, dann fügt man es nicht in der Ausgabe ein.

Hat gegenüber der auch gültigen Methode von Firefall den Vorteil, dass es eine O(n) statt einer O(n²)-Operation ist. Der Code wird dadurch natürlich auch nicht kürzer als 10 Zeilen ;)

PS: Ich glaube nicht, dass dies mit Regex gehen täte, das ist eigentlich schon so was wie ein Klammerausdruck ;)

Firefall
10.01.2008, 23:51
geht sogar noch etwas effizienter:

man nehme einen beliebigen assoziativen Container in der Progsprache der Wahl (auch Hashtabelle genannt). In die speichert man jedes Zeichen der Eingabe, das dort nicht vorhanden ist ein. Sollte das Zeichen schon im Container sein, dann fügt man es nicht in der Ausgabe ein.

Hat gegenüber der auch gültigen Methode von Firefall den Vorteil, dass es eine O(n) statt einer O(n²)-Operation ist. Der Code wird dadurch natürlich auch nicht kürzer als 10 Zeilen ;)

PS: Ich glaube nicht, dass dies mit Regex gehen täte, das ist eigentlich schon so was wie ein Klammerausdruck ;)
:D Den Unterschied sehe ich nicht, verstehe ich da was falsch? Was unterscheidet dein "Hashtable" von meinem String2?

eViL_oNe
10.01.2008, 23:58
ganz einfach: in einem String musst du nach einem Zeichen linear suchen. In einer Hashtabelle hast du die Existenz von dem Zeichen sofort (es sei denn, die Hashfunktion ist schlecht implementiert, ich will aber mal einfach unterstellen, dass das unter Perl schon gut gelöst ist).

sehen wir es also mal im Detail an:

Lösung mit String: Schleife mit n Durchläufen mit einer darin enthaltenen Operation, die intern bis zu n Durchläufe braucht

Lösung mit Hashtable: Schleife mit n Durchläufen mit einer darin enthaltenen Operation, die im MITTEL einen Durchlauf braucht

also auf der einen Seite eine Komplexität von O(n*n), auf der anderen etwa O(n) (was aufgrund von möglichen Konflikten nicht ganz stimmt).

Auch das interne Speicherverhalten sollte nciht allzu unterschiedlich ausfallen, denn sowohl strings als auch hashtables müssen irgendwann neu erzeugt werden (wenn der interne Platz zu klein wird) ;)

PS: Wenn wir schon dabei sind: es stimmt nicht ganz, dass man einen beliebigen assoziativen Container nehmen kann. Es gibt nämlich Progsprachen, wo diese als Binärbäume umgesetzt sind (in Java etwa SortedMap/SortedSet statt HashMap/HashSet oder LinkedHashMap/LinkedHashSet) -- hier hat die Existenzabfrage O(log n), was natürlich immer noch besser ist als O(n) aber doch schlechter als O(1).

Firefall
11.01.2008, 00:03
ganz einfach: in einem String musst du nach einem Zeichen linear suchen. In einer Hashtabelle hast du die Existenz von dem Zeichen sofort (es sei denn, die Hashfunktion ist schlecht implementiert, ich will aber mal einfach unterstellen, dass das unter Perl schon gut gelöst ist).

sehen wir es also mal im Detail an:

Lösung mit String: Schleife mit n Durchläufen mit einer darin enthaltenen Operation, die intern bis zu n Durchläufe braucht

Lösung mit Hashtable: Schleife mit n Durchläufen mit einer darin enthaltenen Operation, die im MITTEL einen Durchlauf braucht

also auf der einen Seite eine Komplexität von O(n*n), auf der anderen etwa O(n) (was aufgrund von möglichen Konflikten nicht ganz stimmt).

Auch das interne Speicherverhalten sollte nciht allzu unterschiedlich ausfallen, denn sowohl strings als auch hashtables müssen irgendwann neu erzeugt werden (wenn der interne Platz zu klein wird) ;)

PS: Wenn wir schon dabei sind: es stimmt nicht ganz, dass man einen beliebigen assoziativen Container nehmen kann. Es gibt nämlich Progsprachen, wo diese als Binärbäume umgesetzt sind (in Java etwa SortedMap/SortedSet statt HashMap/HashSet oder LinkedHashMap/LinkedHashSet) -- hier hat die Existenzabfrage O(log n), was natürlich immer noch besser ist als O(n) aber doch schlechter als O(1).Okay, ich schätze ich muss mich besser über Hashtables informieren ;) Danke für die Erläuterung!
EDIT: Ok jetz ist glasklar, war gestern ein wenig durcheinander... Das Ausdruck "Hash" hat mich verwirrt :) Hätte ich selber drauf kommen müssen...

DrWhiteLetter
11.01.2008, 13:34
Die Aufgabe war eine Cäsar-Verschlüsselung zu Programmieren, ich habs nun so gelöst, dass der Lehrer auch ordentlich was zu tun hat (deshalb wollte ich eigentlich auch einen RegEx verwenden).


perl -e '$\="\n";@b=@ARGV;for(a..z){$a.=$_}for(split/(?=.)/,$b[0]){$x.=$&if($a=~s/$_//)}for(split/(?=.)/,$a){$d=$_.$d}$_=lc$b[1];$b="$x$d/a-z";$b="a-z/$x$d"if($b[2]);eval"tr/$b/";print' Schlüssel "Zu verschlüsselnder Text"