Autor Beitrag
Chrisel
Hält's aus hier
Beiträge: 1



BeitragVerfasst: 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:
ausblenden 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]; //Hier gibts extreme Probleme... Bei Text[1] gibts einen Zugriffsfehler..keine ahnung warum
    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
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
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)
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Administrator
Beiträge: 217
Erhaltene Danke: 96



BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19339
Erhaltene Danke: 1752

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Fr 27.08.10 06:02 
user profile iconTankard hat folgendes geschrieben Zum zitierten Posting springen:
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.

user profile iconChrisel hat folgendes geschrieben Zum zitierten Posting springen:
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? :gruebel:

user profile iconChrisel hat folgendes geschrieben Zum zitierten Posting springen:
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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 591
Erhaltene Danke: 14



BeitragVerfasst: 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:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
var TextFile : file of char;
    nch : char;
    CharFrequency : array [0..255of integer;
{  ... assign, open etc. }

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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2684
Erhaltene Danke: 32



BeitragVerfasst: Fr 27.08.10 18:09 
user profile iconReinhard Kern hat folgendes geschrieben Zum zitierten Posting springen:
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. ;)
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19339
Erhaltene Danke: 1752

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 591
Erhaltene Danke: 14



BeitragVerfasst: Fr 27.08.10 23:25 
user profile icondelfiphan hat folgendes geschrieben Zum zitierten Posting springen:
user profile iconReinhard Kern hat folgendes geschrieben Zum zitierten Posting springen:
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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2684
Erhaltene Danke: 32



BeitragVerfasst: Sa 28.08.10 00:01 
user profile iconReinhard Kern hat folgendes geschrieben Zum zitierten Posting springen:
user profile icondelfiphan hat folgendes geschrieben Zum zitierten Posting springen:
user profile iconReinhard Kern hat folgendes geschrieben Zum zitierten Posting springen:
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.

user profile iconReinhard Kern hat folgendes geschrieben Zum zitierten Posting springen:
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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 591
Erhaltene Danke: 14



BeitragVerfasst: Sa 28.08.10 12:40 
user profile icondelfiphan hat folgendes geschrieben Zum zitierten Posting springen:
user profile iconReinhard Kern hat folgendes geschrieben Zum zitierten Posting springen:
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 ;)


Da würde ich ja auch eine intelligentere Verwaltung einsetzen, die nur die tatsächlich vorkommenden Buchstaben berücksichtigt, aber dann ist es halt kein trivialer 2Zeiler mehr.

Gruss Reinhard
Martok
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 3661
Erhaltene Danke: 604

Win 8.1, Win 10 x64
Pascal: Lazarus Snapshot, Delphi 7,2007; PHP, JS: WebStorm
BeitragVerfasst: Sa 28.08.10 14:52 
user profile iconReinhard Kern hat folgendes geschrieben Zum zitierten Posting springen:
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."