AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren

Leerzeichen in String einfügen

Ein Thema von majornudelholz · begonnen am 26. Jan 2016 · letzter Beitrag vom 2. Feb 2016
Antwort Antwort
Dejan Vu
(Gast)

n/a Beiträge
 
#1

AW: Leerzeichen in String einfügen

  Alt 27. Jan 2016, 06:48
Bei 192 Zeichen dürften das 'schneller' weit jenseits der Messbarkeit sein.
Delphi-Quellcode:
var
  i : Integer;
  
begin
  i := 4; // Erste Einfügeposition hinter der 4 Stelle.
  while i < Length(Text) do begin
    insert (Text, i,'_');
    inc(i,5); // weil man ja nun 5 Zeichen weiter rutschen muss
  end;
End;
Getippt und nicht getestet. Sollte aber so oder ähnlich gehen.

Übrigens: Bisschen kleiner, leichter zu verstehen, geradliniger.
  Mit Zitat antworten Zitat
HolgerX

Registriert seit: 10. Apr 2006
Ort: Leverkusen
981 Beiträge
 
Delphi 6 Professional
 
#2

AW: Leerzeichen in String einfügen

  Alt 27. Jan 2016, 07:23
Hmm..

Oder mach es doch einfach mit einer rückwärts laufenden Schleife

Delphi-Quellcode:
function InsertUnderLine(AText : string; aPos : byte):string;
var
  i : integer;
begin
  result := AText;
  for i := length(AText)-1 downto 1 do begin
    if ((i mod aPos) = 0) then
      insert('_',result,i+1);
  end;
end;
Mit 'for' kann man nicht nur 'hochzählen' sondern auch 'runterzählen'
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#3

AW: Leerzeichen in String einfügen

  Alt 27. Jan 2016, 08:00
Oder mit ganz wenigen String-Kopierorgien und einem wahlfreien String den man dort einschieben kann:
Delphi-Quellcode:
function StrInsertEveryNthPos( const AStr, AInsertStr: string; APos: integer ): string;
var
  OffSet : integer;
  ResLen, ResIdx, StrIdx, InsIdx: integer;
begin
  // OffSet for ZEROBASED STRINGS
  OffSet := 1 - low( string );

  // Calculate result length

  ResLen := ( Length( AStr ) div APos );
  if Length( AStr ) mod APos = 0
  then
    Dec( ResLen );
  ResLen := Length( AInsertStr ) * ResLen;
  ResLen := ResLen + Length( AStr );

  SetLength( Result, ResLen );

  // Build result

  ResIdx := 1;

  for StrIdx := 1 to Length( AStr ) do
    begin
      Result[ ResIdx - OffSet ] := AStr[ StrIdx - OffSet ];
      Inc( ResIdx );

      // Insert the AInsertStr

      if ( StrIdx mod APos = 0 ) and ( StrIdx < Length( AStr ) )
      then
        for InsIdx := 1 to Length( AInsertStr ) do
          begin
            Result[ ResIdx - OffSet ] := AInsertStr[ InsIdx - OffSet ];
            Inc( ResIdx );
          end;
    end;
end;
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
Benutzerbild von Mavarik
Mavarik

Registriert seit: 9. Feb 2006
Ort: Stolberg (Rhld)
4.154 Beiträge
 
Delphi 10.3 Rio
 
#4

AW: Leerzeichen in String einfügen

  Alt 27. Jan 2016, 09:57
@Sir Rufo sehr nice und wie immer natürlich variable und "zu gebrauchen"
@EgonHugeist der Quadmove ist natürlich sehr nett, aber da durch brauchst Du drumrum natürlich mehr...
Wäre zu testen ob der Quadmove das wett macht...

Alle Routinen mit Insert - gehen natürlich gar nicht - weil der String nicht nur 192 Zeichen, sondern auch mal 20MB lang seinen kann...

Die Frage ist, wenn der String Steuerzeichen hat - wie #13#10 oder #10#13 oder nur #10 oder #13... Beginnt der Zähler dann bei 0? Und natürlich darf das " " oder "_" nicht zwischen #13_#10 eingefügt werden...

Kommt Leute da geht noch was...

Geändert von Mavarik (27. Jan 2016 um 10:01 Uhr)
  Mit Zitat antworten Zitat
EgonHugeist

Registriert seit: 17. Sep 2011
187 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#5

AW: Leerzeichen in String einfügen

  Alt 27. Jan 2016, 10:48
@mav

meine Portierung hält sich exakt an das, was der TE wollte. Ich halte es für abwägig, das LineEndings oder andere ctrl chars im TEdit landen...

Klar geht noch was:

Code:
function EH_QuadUnderScoreFillerBy4(Const Text: String): String;
type PMyQuadMover = {$IFDEF UNICODE}PUInt64{$ELSE}PLongWord{$ENDIF};
var
  Src, Dest, PEnd: PChar;
  SrcLen: Integer;
begin
  if Text = '' then
    Result :=''
  else begin
    SrcLen := PLongInt(NativeUInt(Text) - SizeOf(LongInt))^; //fast get src length
    Src := Pointer(Text);
    PEnd := Src+SrcLen-5;
    if (Pointer(Result) = nil) or //result unassigned?
       (PLongInt(NativeUInt(Result) - SizeOf(LongInt))^ <> SrcLen) {PStrRec.Len} or //length different?
       (PLongInt(NativeUInt(Result) - (SizeOf(LongInt) shl 1))^ <> 1) {PStrRec.RefCnt} then //no unique string?
      SetLength(Result,SrcLen+((SrcLen-1) shr 2));
    Dest := Pointer(Result);
    while (Src <= PEnd) do begin//making a quad processing loop
      PMyQuadMover(Dest)^ := PMyQuadMover(Src)^;
      (Dest+4)^ := '_';
      Inc(Dest, 5);
      Inc(Src, 4);
    end;
    Inc(PEnd, 4);
    while Src < PEnd do //processing final chars
    begin
      Dest^ := Src^;
      Inc(Src);
      Inc(Dest);
    end;
    Dest^ := Src^; //null term save
  end;
end;
und nu 2 quad moves in einer loop (macht nur sinn, wenn der String länger ist)
Code:
function EH_QuadUnderScoreFillerBy8(Const Text: String): String;
type PMyQuadMover = {$IFDEF UNICODE}PUInt64{$ELSE}PLongWord{$ENDIF};
var
  Src, Dest, PEnd: PChar;
  SrcLen: Integer;
begin
  if Text = '' then
    Result :=''
  else begin
    SrcLen := PLongInt(NativeUInt(Text) - SizeOf(LongInt))^; //fast get src length
    Src := Pointer(Text);
    PEnd := Src+SrcLen-9;
    if (Pointer(Result) = nil) or //result unassigned?
       (PLongInt(NativeUInt(Result) - SizeOf(LongInt))^ <> SrcLen) {PStrRec.Len} or //length different?
       (PLongInt(NativeUInt(Result) - (SizeOf(LongInt) shl 1))^ <> 1) {PStrRec.RefCnt} then //no unique string?
      SetLength(Result,SrcLen+((SrcLen-1) shr 2));
    Dest := Pointer(Result);
    while (Src <= PEnd) do begin//making a octed processing loop
      PMyQuadMover(Dest)^ := PMyQuadMover(Src)^;
      (Dest+4)^ := '_';
      PMyQuadMover(Dest+5)^ := PMyQuadMover(Src+4)^;
      (Dest+9)^ := '_';
      Inc(Dest, 10);
      Inc(Src, 8);
    end;
    Inc(PEnd, 8);
    if ((Src+4) <= PEnd) then begin//making final quad move
      PMyQuadMover(Dest)^ := PMyQuadMover(Src)^;
      (Dest+4)^ := '_';
      Inc(Dest, 5);
      Inc(Src, 4);
    end;
    while Src < PEnd do //processing final chars
    begin
      Dest^ := Src^;
      Inc(Src);
      Inc(Dest);
    end;
    Dest^ := Src^; //null term save
  end;
end;
Jup mehr drum herum, ist nicht abzustreiten. Jags mal durch nen Tick-Counter mit 'ner loop x 5.000.000 ich garantier dir der Unterschied ist riesig.

Das gilt im PurePascal erst mal zu Schlagen! Wer traut sich?

Gruß vom ZeosDevTeam

Edit: a shr vs shl war verdreht, sorry sonst funzt das "Reuse-Result" nicht

Geändert von EgonHugeist (27. Jan 2016 um 11:37 Uhr) Grund: typo
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#6

AW: Leerzeichen in String einfügen

  Alt 27. Jan 2016, 10:49
Die Frage ist, wenn der String Steuerzeichen hat - wie #13#10 oder #10#13 oder nur #10 oder #13... Beginnt der Zähler dann bei 0? Und natürlich darf das " " oder "_" nicht zwischen #13_#10 eingefügt werden...
Dann kommt wieder Composite ins Spiel.
  • String in Zeilen splitten
  • Jede Zeile durch die Routine
  • Zeilen wieder zusammenfassen
Eine zu starke Spezialisierung macht keinen Sinn, denn mal ist ein Zeilenumbruch #10 mal #13 mal #13#10 ... und dann werden die Zeilen an weiß der Geier woran umgebrochen (HTML bei einem <br>)
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.342 Beiträge
 
Delphi 12 Athens
 
#7

AW: Leerzeichen in String einfügen

  Alt 27. Jan 2016, 12:29
Dann kommt wieder Composite ins Spiel.
Wie Recht du doch hast.

A: Surrogates und bei ANSI die MultiByte-Zeichensätze > https://de.wikipedia.org/wiki/UTF-16
B: Ä kann auch als A mit ¨ geschrieben werden > https://en.wikipedia.org/wiki/Precomposed_character https://en.wikipedia.org/wiki/Composite_character https://de.wikipedia.org/wiki/%C3%84 https://de.wikipedia.org/wiki/Trema https://de.wikipedia.org/wiki/Unicod...tische_Zeichen ...

MSDN-Library durchsuchenCharNext / MSDN-Library durchsuchenCharNextEx
Ein Therapeut entspricht 1024 Gigapeut.

Geändert von himitsu (27. Jan 2016 um 12:43 Uhr)
  Mit Zitat antworten Zitat
EgonHugeist

Registriert seit: 17. Sep 2011
187 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#8

AW: Leerzeichen in String einfügen

  Alt 27. Jan 2016, 12:42
Zum Spaß, hab ich mal ne kleine Benchmark Sache gemacht..

Zitat:
Benchmarking(x16 x 2.000.000):
Autor: Maverik Function: MaverikQuadUnderScoreInjector between 9734

Benchmarking(x16 x 2.000.000):
Autor: EgonHugeist Function: leerzeichen between 3500

Benchmarking(x16 x 2.000.000):
Autor: EgonHugeist Function: EH_QuadUnderScoreInjectorBy4 between 3453

Benchmarking(x16 x 2.000.000):
Autor: EgonHugeist Function: EH_QuadUnderScoreInjectorBy8 between 3437
Habe mal laaaange strings unterdrückt, da MaverikQuadUnderScoreInjector etwas laaange braucht.
@Sir Rufo
Darf ich deine Resultate zum Spaß beihängen? Habe ne kleine Test-Unit gebastelt. Mit deiner StrInsertEveryNthPos function..

Sonst würd ich die wieder rausnehmen und nur für Maverik der Validierung halber anhängen..
  Mit Zitat antworten Zitat
EgonHugeist

Registriert seit: 17. Sep 2011
187 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#9

AW: Leerzeichen in String einfügen

  Alt 27. Jan 2016, 08:12
Da es sich explizit um Quad Folgen handelt..

@Maverik ungetestet aus dem Handgelenk geschüttelt:
edit:
Hab's nun doch getestet und da hat noch das mod gefehlt, sonst hängt man auch noch '_' and den letzten quad an

Code:
function leerzeichen(Const Text: String): String;
type PMyQuadMover = {$IFDEF UNICODE}PUInt64{$ELSE}PLongWord{$ENDIF};
var
  Src, Dest, PEnd: PChar;
begin
  if Text = '' then
    Result :=''
  else begin
    SetLength(Result,length(Text)+(Length(Text) div 4)-Ord(Length(Text) mod 4 = 0));
    PEnd := PChar(@Text[Length(Text)])-4;
    Dest := Pointer(Result);
    Src := Pointer(Text);
    while (Src <= PEnd) do begin//making a quad processing loop
      PMyQuadMover(Dest)^ := PMyQuadMover(Src)^;
      (Dest+4)^ := '_';
      Inc(Dest, 5);
      Inc(Src, 4);
    end;
    Inc(PEnd, 4);
    while Src < PEnd do //processing final chars
    begin
      Dest^ := Src^;
      Inc(Src);
      Inc(Dest);
    end;
    Dest^ := Src^; //null term save
  end;
end;
Das wäre schnell.. man könnte die Loops auch nach auf octets erhöhen, auf RefCount und Length vorher testen usw ..

Geändert von EgonHugeist (27. Jan 2016 um 08:55 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort

 
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 04:51 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz