AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren

Array Inhalt versetzen?

Ein Thema von MicMic · begonnen am 7. Mai 2020 · letzter Beitrag vom 10. Mai 2020
Antwort Antwort
DieDolly

Registriert seit: 22. Jun 2018
2.175 Beiträge
 
#1

AW: Array Inhalt versetzen?

  Alt 8. Mai 2020, 17:21
Zitat:
Ist halt nicht so einfach auf variable Arraylängen anpassbar.
Verstehe das Problem nicht. Das ist ein einfacher Switch über ein string array.
  Mit Zitat antworten Zitat
Medium

Registriert seit: 23. Jan 2008
3.688 Beiträge
 
Delphi 2007 Enterprise
 
#2

AW: Array Inhalt versetzen?

  Alt 8. Mai 2020, 18:09
Zitat:
Ist halt nicht so einfach auf variable Arraylängen anpassbar.
Verstehe das Problem nicht. Das ist ein einfacher Switch über ein string array.
Nein. Der Fragesteller möchte nicht 2 Elemente tauschen, sondern das erste zum letzten machen, und alle nach dem ersten sollen um einen Indext nach unten rutschen. (Und auch den umgekehrten Weg.) Hatte mich bei deiner ersten Antwort schon gewundert, was das mit dem Problem des TE zu tun hat - außer man rauscht ein Mal kräftig auf "komplizierte" Weise durch das ganze Array.
"When one person suffers from a delusion, it is called insanity. When a million people suffer from a delusion, it is called religion." (Richard Dawkins)
  Mit Zitat antworten Zitat
MicMic

Registriert seit: 26. Mai 2018
296 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#3

AW: Array Inhalt versetzen?

  Alt 9. Mai 2020, 08:03
Die eine Richtung mit:
Code:
 SetLength(A,Length(A)+1);
 Insert(A[Length(A)-1], A, 0);
 Delete(A,Length(A)-1,1);
 SetLength(A,Length(A)-1);
die nur mit "SetLength+1" und "SetLength-1" geht, habe ich geändert.

Nur ein:
Code:
 Insert(A[Length(A)-1], A, 0);
 Delete(A,Length(A)-1,1);
reicht aber hier nicht. Er setzt hier den vorletzten Eintrag an den Anfang. Auf den letzten Eintrag im Array habe ich gar keinen Zugriff. Das lieg wohl am Aufbau von "Insert" (wegen "Length(A)-1").

Ich habe mir jedenfalls entsprechende Prozeduren gemacht (für beide Richtungen):
Code:
 Procedure TabToLeft(Var A:TArray<String>);
 Begin
   Insert(A[0], A, Length(A));
   Delete(A,0,1);
 End;

 Procedure TabToRight(Var A:TArray<String>);
 Var S : String;
 Begin
  S := A[Length(A)-1];
  Insert(S, Splitted, 0);
  Delete(A,Length(A)-1,1);
 End;
So geht's dann komplett ohne "SetLength".

Danke für die Hilfe meiner Problemlösung.

Gruß Micha
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

AW: Array Inhalt versetzen?

  Alt 9. Mai 2020, 14:40
Ohh, eigentlich sollte der Wert vorher kopiert und als Parameter übergeben werden,
aber könnte wirklich sein, dass hier die Compilermagic und Codeoptimierung durchschlägt, da Insert und Delete nicht wirklich so richtige "normale" Prozeduren sind.

Über die Record-Operatoren hast hier dann mehr Glück, weil die komplett extrem unoptimierbar sind.


Nja, direkt ist es so eigentlich auch nicht optimal, denn hier wird ja zwei mal die Länge des Arrays geändert und im extremfall auch alles bis zu zwei Mal komplett umkopiert.
Ein Therapeut entspricht 1024 Gigapeut.

Geändert von himitsu ( 9. Mai 2020 um 14:42 Uhr)
  Mit Zitat antworten Zitat
Andreas13

Registriert seit: 14. Okt 2006
Ort: Nürnberg
727 Beiträge
 
Delphi XE5 Professional
 
#5

AW: Array Inhalt versetzen?

  Alt 9. Mai 2020, 15:17
Anstatt der Änderung der Array-Länge und des damit verbundenen (internen) Umkopierens der Inhalte könntest Du relativ einfach eine Art von Ringpuffer realisieren. Hierbei würde lediglich ein Zeiger auf das Array-Element zeigen und Du könntest diesen Zeiger (Pointer) Inkrementieren bzw. Dekrementieren und den Inhalt nur im Bedarfsfall anzeigen. Allerdings weiß ich nicht, ob eine solche Lösung zu Deiner Anwendung passt oder nicht.
Gruß, Andreas
Grüße, Andreas
Wenn man seinem Nächsten einen steilen Berg hinaufhilft, kommt man selbst dem Gipfel näher. (John C. Cornelius)
  Mit Zitat antworten Zitat
Andreas13

Registriert seit: 14. Okt 2006
Ort: Nürnberg
727 Beiträge
 
Delphi XE5 Professional
 
#6

AW: Array Inhalt versetzen?

  Alt 9. Mai 2020, 15:22
Noch einfacher wäre ein gleichlanges Integer-Array, in welchem die Elemente auf die gewünschte Position des String-Arrays zeigen. Damit kannst Du die Reihenfolge durch Änderung der "Integer-Zeiger" einfach ändern und auch die String-Inhalte
StringArray[IntegerArray[i]] anzeigen.
Grüße, Andreas
Wenn man seinem Nächsten einen steilen Berg hinaufhilft, kommt man selbst dem Gipfel näher. (John C. Cornelius)
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.715 Beiträge
 
Delphi 12 Athens
 
#7

AW: Array Inhalt versetzen?

  Alt 9. Mai 2020, 15:58
Noch einfacher wäre ein gleichlanges Integer-Array, in welchem die Elemente auf die gewünschte Position des String-Arrays zeigen.
Da die Strings selbst auch nur als Pointer in den Array-Elementen vorliegen, ergibt sich m.E. hier kein nennenswerter Vorteil.

Ich kann auch mit folgendem Code keinen Fehler feststellen (getestet in 10.3.3):
Delphi-Quellcode:
procedure RotateRight(var A: TArray<String>);
begin
  Insert(A[Length(A)], A, 0);
  Delete(A, High(A), 1);
end;

procedure RotateLeft(var A: TArray<String>);
begin
  Insert(A[0], A, Length(A));
  Delete(A, 0, 1);
end;
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

AW: Array Inhalt versetzen?

  Alt 10. Mai 2020, 12:43
Hatte nicht nachgesehn, aber würde dann das hier bestätigen.
Ohh, eigentlich sollte der Wert vorher kopiert und als Parameter übergeben werden,
aber könnte wirklich sein, dass hier die Compilermagic und Codeoptimierung durchschlägt, da Insert und Delete nicht wirklich so richtige "normale" Prozeduren sind.
Ein Therapeut entspricht 1024 Gigapeut.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

AW: Array Inhalt versetzen?

  Alt 10. Mai 2020, 13:27
Man könnte es jetzt so lösen und die Prüfung deaktivieren.
Delphi-Quellcode:
procedure RotateRight(var A: TArray<String>);
begin
  {$RANGECHECKS OFF}
  Insert(A[Length(A)], A, 0);
  Delete(A, High(A), 1);
  //{$RANGECHECKS ON} = Default ist OFF
end;

procedure RotateRight(var A: TArray<String>);
begin
  {$UNDEF _TEMP_}
  {$IFOPT R+} {$DEFINE _TEMP_} {$ENDIF}  
  {$RANGECHECKS OFF}
  Insert(A[Length(A)], A, 0);
  Delete(A, High(A), 1);
  {$IFDEF _TEMP_} {$RANGECHECKS ON} {$ENDIF}  
end;
Aber wenn irgendwann am Verhalten von INSERT was geändert wird und es dann "richtig" funktioniert,
oder wenn es schon jetzt auf verschiedenen Plattformen unterschiedliche arbeitet (Win64, Android, ...),
dann hast ein Problem.

Effektiv verbleibt aber diese Lösung:
Delphi-Quellcode:
procedure RotateRight(var A: TArray<String>);
var
  T: Temp;
begin
  T := A[High(A)];
  Insert(T, A, 0);
  Delete(A, High(A), 1);
end;

// oder :lol:
procedure RotateRight(var A: TArray<String>);
begin
  Insert(StrToInt(IntToStr(A[High(A)])), A, 0); // oder Insert(Min(A[High(A)], A[High(A)]), A, 0);
  Delete(A, High(A), 1);
end;
Test-Code:
Delphi-Quellcode:
var
  i, j: Integer;
  A: TArray<Byte>;
  B: array[0..7] of string;
begin
  {$RANGECHECKS OFF}
  SetLength(A, 10);
  for i := 0 to High(B) do
    B[i] := StringOfChar('_', 12 * 2) + ' ';

  // move first +1
  for i := 0 to High(A) do A[i] := $80 or i;
  Insert(A[Length(A)], A, 0); BinToHex(A[0], PChar(B[0]), Length(A));
  Delete(A, High(A), 1); BinToHex(A[0], PChar(B[1]), Length(A));

  // move first
  for i := 0 to High(A) do A[i] := $80 or i;
  Insert(A[High(A)], A, 0); BinToHex(A[0], PChar(B[2]), Length(A));
  Delete(A, High(A), 1); BinToHex(A[0], PChar(B[3]), Length(A));

  // move first none-optimize
  {$OPTIMIZATION OFF}
  for i := 0 to High(A) do A[i] := $80 or i;
  Insert(A[High(A)], A, 0); BinToHex(A[0], PChar(B[4]), Length(A));
  Delete(A, High(A), 1); BinToHex(A[0], PChar(B[5]), Length(A));
  {$OPTIMIZATION ON}

  // move last
  for i := 0 to High(A) do A[i] := $80 or i;
  Insert(A[0], A, Length(A)); BinToHex(A[0], PChar(B[6]), Length(A));
  Delete(A, 0, 1); BinToHex(A[0], PChar(B[7]), Length(A));

  for i := 0 to High(B) do for j := Length(A) downto 0 do Insert(' ', B[i], j * 2 + 3);
  ShowMessage(
    B[0] + 'first+1'#10 + B[1] + #10#10 +
    B[2] + 'first'#10 + B[3] + #10#10 +
    B[4] + 'first no'#10 + B[5] + #10#10 +
    B[6] + 'last'#10 + B[7]);
end;
Delete hat das Problem natürlich nicht, denn hier muß ja zuerst ausgelesen werden und dann wird damit die Länge geändert.
Delphi-Quellcode:
var
  i: Integer;
  A: TArray<Byte>;
  B: string;
begin
  SetLength(A, 10);
  for i := 0 to High(A) do A[i] := i;
  B := StringOfChar('_', Length(A) * 2);

  Delete(A, A[5], 1);

  BinToHex(A[0], PChar(B), Length(A));
  for i := Length(A) downto 0 do Insert(' ', B, i * 2 + 3);
  ShowMessage(B);
end;
Ein Therapeut entspricht 1024 Gigapeut.

Geändert von himitsu (10. Mai 2020 um 13:39 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 09:13 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