| Autor |
Beitrag |
Chrisel
Hält's aus hier
Beiträge: 1
|
Verfasst: Do 26.08.10 23:23
Hallo alle zusammen:)
Ich versuche momentan ein Programm zu schreiben wo ich die vorhandenen zeichen in einem Text auslesen möchte.
Es geht darum das ich alle zeichen des Textes mit einem bestimmten ersetzten möchte so das nur noch das "Muster" von Text überbleibt. Ich verzweifele gerade bloß daran wie ich alle zeichen die vorkommen in eine array bekomme.
Kann mir da jemand vielleicht helfen?
Mein Ansatz wäre ungefähr so:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12:
| Text:='1'+Eingabe.Text; grzahl:=0; for zeile := 0 to Length(Text) do begin Bs:=Text[2]; anzahl:=Zeichenzaehlen(Text,Bs); Text:=StringReplace(Text,Bs,'',[rfReplaceAll]); if anzahl>grzahl then begin grzahl:=anzahl; grbs:=bs; end; |
Habe mir das halt so gedacht das ein Zeichen sich gemerkt wird, dann sollte das in die array, dann sollen alle zeichen davon gelöscht werden und dann soll das gleiche mit dem nächsten gemacht werden...Ein Problem habe ich als Kommentar oben schon beschrieben was bedeutet das ich mein vorhaben auch nicht alle zeichen ausgelesen werden. Mein Zweites Problem ist die geschwindigkeit: ich weiß ja nicht wieviel verschiedene buchstaben enthalten sind aber die einträge in die array sollen möglichst wenig sein. also nicht sowas wie:['a','g','w','f','','',''] sondern eher so:['a','g','w','f']
Hoffe mir kann jemand helfen
Danke schonmal für eure Antworten:)
Viele Grüße
Chrisel
|
|
Bergmann89
      
Beiträge: 1742
Erhaltene Danke: 72
Win7 x64, Ubuntu 11.10
Delphi 7 Personal, Lazarus/FPC 2.2.4, C, C++, C# (Visual Studio 2010), PHP, Java (Netbeans, Eclipse)
|
Verfasst: Do 26.08.10 23:55
Hey,
wenn Text vom Typ String ist, dann darfst du nich das 0-Element lesen, da kommt dann der Fehler. String gehen prozipiell von 1 bis Length(Text).
MfG Bergmann
_________________ Ich weiß nicht viel, lern aber dafür umso schneller^^
|
|
Tankard
      

Beiträge: 217
Erhaltene Danke: 96
|
Verfasst: Fr 27.08.10 04:46
string[0] kann man lesen, nur beschreiben sollte man es nicht. da in string[0] die länge des strings steht.
alla wirth´s ist das ok. daran halten sich normalerweise auch alle.
|
|
jaenicke
      
Beiträge: 19339
Erhaltene Danke: 1752
W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Fr 27.08.10 06:02
Tankard hat folgendes geschrieben : | | string[0] kann man lesen, nur beschreiben sollte man es nicht. da in string[0] die länge des strings steht. |
Das war vor 15 Jahren bei Delphi 1 so und ist heute nur noch bei den selten verwendeten ShortStrings so...
Ein String ist heute ein Pointer auf eine Zeichenkette, vor deren Anfang (also in dem Bereich vor dem, auf den der Pointer zeigt) die Länge als 4-Byte-Integer steht und danach der Referenzzähler, ebenfalls 4 Byte. Mit dem Index 0 kommst du also dort mit Sicherheit nicht mehr an die Länge und das sagt dir Delphi beim Versuch zu kompilieren auch AFAIK.
Chrisel hat folgendes geschrieben : | | Es geht darum das ich alle zeichen des Textes mit einem bestimmten ersetzten möchte so das nur noch das "Muster" von Text überbleibt. Ich verzweifele gerade bloß daran wie ich alle zeichen die vorkommen in eine array bekomme. |
Wenn du ohnehin alle ersetzen willst, wozu brauchst du dann ein Array mit den Buchstaben?
Chrisel hat folgendes geschrieben : | | Mein Zweites Problem ist die geschwindigkeit: ich weiß ja nicht wieviel verschiedene buchstaben enthalten sind aber die einträge in die array sollen möglichst wenig sein. also nicht sowas wie:['a','g','w','f','','',''] sondern eher so:['a','g','w','f'] |
Du widersprichst dir selbst. Geschwindigkeit hieße, dass man ignoriert, wenn Buchstaben nicht vorkommen und im Array einfach diese Zeichen mit eintragen würde, aber eben als nicht vorhanden. Zudem eignet sich eher ein Array of Boolean, wenn du wissen willst ob ein Buchstabe vorkommt bzw. ein Array of Integer, wenn du wissen willst wie oft ein Buchstabe vorkommt.
In jedem Fall ist ein StringReplace hier der absolute Geschwindigkeitskiller...
Geh lieber selbst zeichenweise durch und mach das alles selbst. 
|
|
Reinhard Kern
      
Beiträge: 591
Erhaltene Danke: 14
|
Verfasst: Fr 27.08.10 16:17
Hallo,
deine Beschreibung ist ziemlich wirr. Aber wenn du die Häufigkeit von Zeichen im Text bestimmen willst und mit 256-Bit-Char auskommst, geht das ziemlich einfach:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10:
| var TextFile : file of char; nch : char; CharFrequency : array [0..255] of integer;
while not eof (TextFile) do begin read (TextFile,nch); inc (CharFrequency [ord(nch)]; end; |
Jetzt wird gleich das übliche Geschrei einsetzen, dass das altmodisch ist und man immer zuerst die ganze Datei in den Speicher lesen muss, anstatt sie zeichenweise zu lesen, aber in Wirklichkeit ändert es am Vorgehen nichts, ob man nun die Verarbeitung per WIN32 API, traditionell read/write, Stream oder LoadFromFile durchführt. Dann verarbeitet man eben aus dem Speicher Zeichen für Zeichen.
Etwas aufwendiger wird es, wenn Char > 256 vorkommen, aber da Speicher ja keine Rolle mehr spielt, kann man auch ein array [0..65535] einrichten, das wird allerdings grössteteils leer bleiben.
Gruss Reinhard
|
|
delfiphan
      
Beiträge: 2684
Erhaltene Danke: 32
|
Verfasst: Fr 27.08.10 18:09
|
|
jaenicke
      
Beiträge: 19339
Erhaltene Danke: 1752
W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Fr 27.08.10 18:52
Bei sehr kleinen Dateien ist es ohnehin egal und bei größeren merkt man eh schnell, dass es zeichenweise direkt aus der Datei keinen Sinn hat, wenn man nen paar Minuten warten muss.
Das ist bei solche einem Beispiel aber ohnehin egal, ich vermute so meintest du das auch.
Ja, was ich eigentlich mit meinem letzten Post meinte war, dass ich glaube, dass das alles gar nicht nötig ist. Es hörte sich doch eher danach an als ob es rein darum ginge jeden Buchstaben durch ein gleiches Zeichen zu ersetzen. Deshalb kann man sich das alles sparen und das einfach nur machen...
|
|
Reinhard Kern
      
Beiträge: 591
Erhaltene Danke: 14
|
Verfasst: Fr 27.08.10 23:25
delfiphan hat folgendes geschrieben : | Reinhard Kern hat folgendes geschrieben : | | Jetzt wird gleich das übliche Geschrei einsetzen, dass das altmodisch ist und man immer zuerst die ganze Datei in den Speicher lesen muss |
Ne, eher blockweise lesen und zählen.  |
Hallo,
das ist rein theoretisch zwar richtig, aber schon die Pascal-Compiler auf CP/M-Z80-Rechnern, mit denen ich mal programmiert habe, haben automatisch eine Buffer-Verwaltung installiert, und alle je existierenden Betriebssysteme lesen sowieso zumindest einen Block bei blockorientierten Dateien in den Speicher, eine eigene Software dafür macht also überhaupt keinen Sinn. Höchstens für Lehrzwecke.
Aber solang sich Chrisel nicht mehr meldet, werden wir nicht dahinterkommen, was er eigentlich wollte.
Gruss Reinhard
|
|
delfiphan
      
Beiträge: 2684
Erhaltene Danke: 32
|
Verfasst: Sa 28.08.10 00:01
Reinhard Kern hat folgendes geschrieben : | delfiphan hat folgendes geschrieben : | Reinhard Kern hat folgendes geschrieben : | | Jetzt wird gleich das übliche Geschrei einsetzen, dass das altmodisch ist und man immer zuerst die ganze Datei in den Speicher lesen muss |
Ne, eher blockweise lesen und zählen.  | das ist rein theoretisch zwar richtig, aber... |
Beim blockweise abarbeiten geht es darum, dass nicht die gesamte Datei in den Speicher geladen wird. Siehe z.B. TStream.CopyFrom, die den gesamten Stream kopiert (aber trotzdem nicht mehrere MB Speicher für die Operation alloziert).
Wie das Betriebssystem die Dateien liest geht mich als Applikationsentwickler überhaupt nichts an.
Reinhard Kern hat folgendes geschrieben : | | Etwas aufwendiger wird es, wenn Char > 256 vorkommen, aber da Speicher ja keine Rolle mehr spielt, kann man auch ein array [0..65535] einrichten, das wird allerdings grössteteils leer bleiben. |
Ja, aber auch nur bei einer UCS-2 Codierung. Seit 2001 gibt's aber mehr als nur 64K 
|
|
Reinhard Kern
      
Beiträge: 591
Erhaltene Danke: 14
|
Verfasst: Sa 28.08.10 12:40
|
|
Martok
      
Beiträge: 3661
Erhaltene Danke: 604
Win 8.1, Win 10 x64
Pascal: Lazarus Snapshot, Delphi 7,2007; PHP, JS: WebStorm
|
Verfasst: Sa 28.08.10 14:52
Reinhard Kern hat folgendes geschrieben : | | das ist rein theoretisch zwar richtig, aber schon die Pascal-Compiler auf CP/M-Z80-Rechnern, mit denen ich mal programmiert habe, haben automatisch eine Buffer-Verwaltung installiert |
Macht Delphi auch, und zwar genauso wie das in TurboPascal schon war: 128byte. Quasi nicht also.
Und man kann den auch nur mit einigem Aufwand vergrößern, z.B. indem man ein paar Funktionspointer umbiegt.
Was der OP will, ist meines Erachtens doch eine Liste der ersten Vorkommen eines jeden Zeichens im String, zusammen mit der Info welches Zeichen am häufigsten kam. Das macht zumindest der Code im 1. Beitrag:
"Hallo Welt" -> {['H','a','l','o',' ','W','e','t'], {'l',3}}
_________________ "The phoenix's price isn't inevitable. It's not part of some deep balance built into the universe. It's just the parts of the game where you haven't figured out yet how to cheat."
|
|
|