Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Ich scheitere grade an simpler Mathematik (https://www.delphipraxis.net/192177-ich-scheitere-grade-simpler-mathematik.html)

hansklok 26. Mär 2017 17:47


Ich scheitere grade an simpler Mathematik
 
Hallo an alle,

eines Vorweg, Mathematik war nie meins :D

Es geht um folgendes. Ich möchte einen Text beliebiger Länge formatiert als String ausgeben. Nehmen wir diesen String als Beispiel:
Code:
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.
Lorem ipsum do
Er hat eine Länge von genau 310 Zeichen. Dieser soll nun in die folgende Struktur umgewandelt werden:
Code:
NOTE Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea t
CONC akimata sanctus est Lorem ipsum dolor sit amet.
CONT Lorem ipsum do
Was sehen wir? Also jede Zeile darf eine maximale Textlänge von 248 Zeichen, ohne die vorangestellten Tags (NOTE, CONC, CONT), haben. Die erste Zeile beginnt immer mit dem Tag NOTE. Gibt es einen Zeilenumbruch, so beginnt die neue Zeile mit CONT, muss die Zeile automatisch umgebrochen werden, weil der Text der Zeile zu lang ist (aktuelle Zeilenlänge > 248 Zeichen), so beginnt die Folgezeile mit CONC.

Wie lässt sich das programmiertechnisch umsetzen?

Besten Dank im Voraus.

Delphi-Laie 26. Mär 2017 18:01

AW: Ich scheitere grade an simpler Mathematik
 
Fehlende mathematische Begabung ist hier kein Hindernis, denn mit Mathematik hat das nicht sonderlich viel zu tun.

Am besten ist es, Du extrahierst immer das entsprechende Anfangsteil dieses Strings und baust in einem neuen String (Anfangslänge 0) dann wieder alles auf, das geht mit simpler "+"-Addition. Zuvor aber Note, Cont und Conc an diesen neuen String anhängen. Das ist m.E. am übersichtlichsten. Etwas komplizierter wird es, wenn Du das alles in den schon vorhanden String integrieren möchtest: Die Zeilenumbrüche und ggf. die Zeilenumbrüche. Dann mußt Du mit einem Integerwert für den laufenden Index arbeiten.

hansklok 26. Mär 2017 18:05

AW: Ich scheitere grade an simpler Mathematik
 
Zitat:

Zitat von Delphi-Laie (Beitrag 1365578)
Fehlende mathematische Begabung ist hier kein Hindernis, den mit Mathematik hat das nicht sonderlich viel zu tun.

Am besten ist es, Du extrahierst immer das entsprechende Anfangsteil dieses Strings und baust in einem neuen String (Anfangslänge 0) dann wieder alles auf, das geht mit simpler "+"-Addition. Zuvor aber Note, Cont und Conc an diesen neuen String anhängen. Das ist m.E. am übersichtlichsten. Etwas komplizierter wird es, wenn Du das alles in den schon vorhanden String integrieren möchtest: Die Zeilenumbrüche und ggf. die Zeilenumbrüche. Dann mußt Du mit einem Integerwert für den laufenden Index arbeiten.

Danke für den ersten Input.

Also ich würde ja erstmal alles in eine Lines-Array splitten (Linebreak). Dann habe ich die Zeilen und diese müssen ja irgendwie nach länge durchlaufen werden und dann u.U. für CONC umgebrochen werden.

nahpets 26. Mär 2017 18:33

AW: Ich scheitere grade an simpler Mathematik
 
Ungetestet hingedaddelt:
Delphi-Quellcode:
const
   ciMaxLineLength = 248;
var
  slIn : TStringList;
  slOut : TStringList;
  i : Integer;
  sLine : String;
begin
  slIn := TStringList.Create;
  slOut := TStringList.Create;
  slIn.LoadFromFile('Eingabe.txt');
  for i := 0 to slIn.Count - 1 do begin
    sLine := slIn[i];
    if i = 0 then slOut.Add('NOTE ' + Copy(sLine,1,ciMaxLineLength)
    else slOut.Add('CONC ' + Copy(sLine,1,ciMaxLineLength);
    while Length(sLine > ciMaxLineLength do begin
      sLine := Copy(sLine,ciMaxLineLength + 1,Length(sLine));
      slOut.Add('CONT ' + Copy(sLine,1,ciMaxLineLength));
    end;
  end;
  slOut.SaveToFile('Ausgabe.txt');
  slOut.Free;
  slIn.Free;
end;

hansklok 28. Mär 2017 12:34

AW: Ich scheitere grade an simpler Mathematik
 
Vielen lieben Dank, ich habe es mittlerweile hinbekommen. :thumb:

himitsu 28. Mär 2017 13:03

AW: Ich scheitere grade an simpler Mathematik
 
Immer schön, wenn dann nicht die Lösung genannt wird.
Da freut sich jeder mit dem gleichen oder einem änlichen Problem, wenn er irgendwann diesen Thread findet.

Zur Aufgabenstellung passend auch eine Lösung mit etwas mehr Mathematik drin.
Delphi-Quellcode:
SL := TStringList.Create;
SL.LoadFromFile('Eingabe.txt');
for i := SL.Count - 1 downto 0 do begin
  SL[i] := IfThen(i = 0, 'NOTE ' , 'CONC ') + SL[i];
  for i2 := (Length(SL[i]) - 1) div 248 downto 1 do
    SL[i] := Copy(SL[i], 1, i2 * 248) + sLineBreak + 'CONT ' + Copy(SL[i], i2 * 248 + 1);
end;
SL.SaveToFile('Ausgabe.txt');
SL.Free;
Angaben ohne Waffe, aber mein verdrehtes Hirn meint es könnt stimmen, was es mal schnell hingetippen lies und nicht getestet hat.

Mit einer Funktion ala SplittString, die aber nach Länge trennt, lässt sich die Schleife auf einen Zweizeiler kürzen.

hansklok 28. Mär 2017 18:22

AW: Ich scheitere grade an simpler Mathematik
 
Zitat:

Zitat von himitsu (Beitrag 1365771)
Immer schön, wenn dann nicht die Lösung genannt wird.
Da freut sich jeder mit dem gleichen oder einem änlichen Problem, wenn er irgendwann diesen Thread findet.

:wink:
Delphi-Quellcode:
Const
  MAX_LENGTH = 248;
Var
  result[]: String;
  lines[]: String = Split(Value, #13#10);
  line: String;
  count, pos, rest: Integer;
  levelStart, levelContinued, levelConcatenate: String;
Begin

  levelStart = IfThen(reference <> "", Join(Array(startLevel, reference, startTag), SPACE), Join(Array(startLevel, startTag), " "));
  levelContinued = Join(Array(Integer(startLevel + 1).ToString, "CONT "), " ");
  levelConcatenate = Join(Array(Integer(startLevel + 1).ToString, "CONC "), " ");

  For i As Integer = 0 To lines.Count Do
 
    pos = 0;
    line= lines[I];
    rest = Lenght(line);
 
    count = Min(MAX_LENGTH, Length(line));
    result.Add(Join(Array(IfThen(i = 0, levelStart, levelContinued), Copy(line, pos, count)), " "));
    rest = rest - count;
 
    While rest > 0 Do Begin
   
      pos = pos + count;
      count = Min(MAX_LENGTH, rest);
      result.Add(Join(Array(levelConcatenate, Copy(line, pos, count)), " "));
      rest = rest - count;
   
    End;
 
  End;

  Return Join(result, #13#10);

End;


Alle Zeitangaben in WEZ +1. Es ist jetzt 22:40 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz