2d Array Ebene 2 drehen?

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
laz847
Beiträge: 114
Registriert: Mi 18. Jun 2014, 16:39

2d Array Ebene 2 drehen?

Beitrag von laz847 »

Hallo zusammen, ich habe ein 2d Array

arrayxy[0..100][dyn]

Die 2 Ebene wird mit Daten gefüllt, dabei wird diese Stück für Stück erweitert. Ich weiß also vorab nicht, wieviele Elemente in Ebene 2 anfallen werden.

Danach benötige ich diese in gedrehter Form, nur die Values der 2 Ebene sollen gedreht werden, Ebene 1 bleibt wie sie ist.

Natürlich kann ich ein tmp Array verwenden und das Array gedreht kopieren aber dabei muss ich natürlich durch jedes Element.

Gibts einen Weg mit mehr Performance? Evtl. irgendwas aus Windows, einer dll oder ähnliches?

DANKE!!

Horst_h
Beiträge: 74
Registriert: Mi 20. Mär 2013, 08:57

Re: 2d Array Ebene 2 drehen?

Beitrag von Horst_h »

Hallo,

wie "gedreht"?
0..100 =X-Achse und dyn sind die diversen Y-werte an der Stelle X.
Was soll da wie gedreht werden.
Beispiel:
0 : 1;12;215;-13
1 : 123;-117
..
100: 1;2;3;4;5;6;7;8;9;10;11;12;13

Gruß Horst

laz847
Beiträge: 114
Registriert: Mi 18. Jun 2014, 16:39

Re: 2d Array Ebene 2 drehen?

Beitrag von laz847 »

Hallo Horst,

ich hab doch gar nichts vom Chart mit Y Werten gesagt lach :D, aber fast richtig im 2 Element liegt ein Record...

Also eigentlich ganz simple, ich hab z.B.

array[100][0] = record0;
array[100][1] = record1;
array[100][2] = record2;
array[100][3] = record3;

brauche aber wenn das Array komplett erstellt wurde

array[100][0] = record3;
array[100][1] = record2;
array[100][2] = record1;
array[100][3] = record0;

Momentan erzeuge ich ein tmp Array und übertrage das gespiegelt auf mein Ziel Array aber bei 100.000 Datensätzen dauert das natürlich etwas.

In anderen Sprachen gibts dazu z.B. den Befehl ArrayReverse(array), in Lazarus habe ich nichts gefunden, deswegen die Frage obs evtl. noch nen Trick gibt?

Danke :D

Komoluna
Beiträge: 565
Registriert: So 26. Aug 2012, 09:03
OS, Lazarus, FPC: Windows(10), Linux(Arch)
CPU-Target: 64Bit

Re: 2d Array Ebene 2 drehen?

Beitrag von Komoluna »

kannst du nicht einfach entweder beim schreieben oder beim auslesen mit

Code: Alles auswählen

for i:=High(array) downto 0 do
...
benutzen?
das hätte die selbe Wirkung, aber benötigt genau 0 zusätzliche Rechenpower...

MFG

Komoluna
Programmer: A device to convert coffee into software.

Rekursion: siehe Rekursion.

Eclipticon
Beiträge: 292
Registriert: Sa 5. Feb 2011, 20:38
OS, Lazarus, FPC: Windows XP VirtualBox (FPC 2.6.4, Laz 1.2.4)
CPU-Target: 32Bit
Wohnort: Wien

Re: 2d Array Ebene 2 drehen?

Beitrag von Eclipticon »

Ich stimme Komoluna zu - anstatt alle Daten umzugraben, waere es nicht einfacher einen Weg zu finden, wie man alternativ auf die Orginaldaten zugreifen kann?

Wenn Du auf einzelne Elemente mit der neuen Indizierung zugreifen moechtest, koennte man ja lt. Deinem Beispiel einfach den Index2 durch

Code: Alles auswählen

High(aarray[100]) - i
ersetzten und den gleichen Effekt erhalten ...

Komoluna
Beiträge: 565
Registriert: So 26. Aug 2012, 09:03
OS, Lazarus, FPC: Windows(10), Linux(Arch)
CPU-Target: 64Bit

Re: 2d Array Ebene 2 drehen?

Beitrag von Komoluna »

Das geht einfach und verbraucht so gut wie keine zusätzlichen Resourcen...

MFG

Komoluna
Programmer: A device to convert coffee into software.

Rekursion: siehe Rekursion.

pluto
Lazarusforum e. V.
Beiträge: 7192
Registriert: So 19. Nov 2006, 12:06
OS, Lazarus, FPC: Linux Mint 19.3
CPU-Target: AMD
Wohnort: Oldenburg(Oldenburg)

Re: 2d Array Ebene 2 drehen?

Beitrag von pluto »

Oder du erstellst es von vornherein so, wie du es gerne hättest.

Ich würde dann zu eine Verketten Liste greifen. Oder eine Pointer "Map"...
MFG
Michael Springwald

Mathias
Beiträge: 6908
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: 2d Array Ebene 2 drehen?

Beitrag von Mathias »

Wie Pluto schon schreibt, würde ich auf jedes Record-Element einen Pointer setzen, somit müssen nur die Pointer, anstelle des ganzen Records getauscht werden.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

laz847
Beiträge: 114
Registriert: Mi 18. Jun 2014, 16:39

Re: 2d Array Ebene 2 drehen?

Beitrag von laz847 »

Hmm ich muss das genauer erklären...

Inhalt rec ist ein Record...

Nehmen wir an ich habe 2 Arrays, ein TMPArray[][rec] und ein Zielarray[][rec].

TMPArray wird zur Laufzeit aus importierten Daten berechnet, dabei weiß ich vorher nie wie gross TMPArray am Ende ist. Und das 2 mal zu berechnen dauert wieder zu lange.

Wenn TMPArray erstellt wurde, weiß ich wie gross es ist, benötige ab jetzt die Daten aber IMMER mit gedrehtem Index.

Anstatt über eine Funktion auf den gedrehten Index zuzugreifen (also bei jedem Zugriff auf Lengt(TMPArray)-1-pos;) fand ich es sinnvoller, dass Array nun einmal zu drehen???

Deswegen kopiere ich mir TMPArray gedreht in Zielarray[], von Zielarray[] weiß ich ja jetzt wie gross es sein muss und kann "den Spiegel" passend erstellen.

Das Ganze passiert aber nun alle 1,3,4,xxx Millisekunden, deswegen die Frage nach anderen Ansätzen, in diesem Bereich merkt man jeden winzigen Unterschied.

Da TMPArray (lokal in function) für weitere Berechnungen verwendet (und nach der Verarbeitung gelöscht wird) wären Zeiger ungültig. Das auch nochmal zu speichern wäre etwas viel, ich halte die Daten bereits im Zielarray (global) für weitere Anfragen bereit.

Achso und Danke für die Antworten ;)!

pluto
Lazarusforum e. V.
Beiträge: 7192
Registriert: So 19. Nov 2006, 12:06
OS, Lazarus, FPC: Linux Mint 19.3
CPU-Target: AMD
Wohnort: Oldenburg(Oldenburg)

Re: 2d Array Ebene 2 drehen?

Beitrag von pluto »

Bei einer Verketten Liste entfällt das Kopieren der Einträge.

Du kannst auch eine Verkette Liste von "hinten" aufbauen. Die Richtung dürfte egal sein.

Such mal nach einfach oder Doppelt Verkette Listen.

Problem ist halt nur, dass du unbedingt ein 2D Array haben möchtest.

Statt ein 2D Array könntest du auch, So eine Struktur wählen:

Liste1[1].Liste2[2].

Weißt du wie ich meine? So kann Liste1 einfach ein einfacher Array sein und liste2 kann jetzt eine verkette Liste sein.
MFG
Michael Springwald

Michl
Beiträge: 2511
Registriert: Di 19. Jun 2012, 12:54

Re: 2d Array Ebene 2 drehen?

Beitrag von Michl »

Kannst auch sowas machen:

Code: Alles auswählen

type
  aArray= Array of Array of aRecord;
 
  TmyClass = class
  private
    function GetZielArray(Index1, Index2: Integer): aRecord;
...
  public
    tmpArray: aArray;
    property ZielArray[Index1, Index2: Integer]: aRecord read GetZielArray;
...
  end;
 
...
function TmyClass.GetZielArray(Index1, Index2: Integer): aRecord;
begin
  if (Index1 <= High(tmpArray)) and
     (Index1 >= 0) and
     (Index2 <= High(tmpArray[Index1])) and
     (Index2 >= 0) then
    Result:=tmpArray[Index1][High(Index1) - Index2]
  else
    Result:=InitARecord;
end; 

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection;  

laz847
Beiträge: 114
Registriert: Mi 18. Jun 2014, 16:39

Re: 2d Array Ebene 2 drehen?

Beitrag von laz847 »

Hi Pluto,

vielen Dank für den Tipp mit den Listen, ich habe mir folgendes mal durchgelesen:
http://www.michael-puff.de/Programmieru ... Delphi.pdf

Prinzip und Vorteile sind klar, in meinem Fall wäre aber die Nutzung von Listen ungünstig. Das Ziel Array ist eigentlich nicht nur 2d sondern 3d.

Ich muss die Boxenwerte (Open,High,Low,Close) für verschiedene Währungen pro Kerze/Bar speichern bzw. im Programm verfügbar halten.

cache[symbolid][bar][ohlc]

Ich habe jetzt in meinem Erklärungen das ZielArray (cache) zur Vereinfachung nur als 2d dargestellt da der Vorgang gleich bleibt.

Ich führe also diesen Importvorgang durch und fülle den Cache mit Daten, der wird natürlich laufend mit den neusten Daten befüllt.

Mein Vorteil dabei ist, ich kann von überall im Programm auf z.B. cache[21][0].Close zugreifen, das vereinfacht natürlich extrem die weitere Programmierung.

[0].Close --> letztes aktuellstes Element vom QuellArray ist im Cache immer auf 0

Zugriff und Verwaltung über Listen würde da glaube ich etwas komplizierter aussehen :roll: ?
Zuletzt geändert von laz847 am Sa 12. Jul 2014, 20:39, insgesamt 1-mal geändert.

laz847
Beiträge: 114
Registriert: Mi 18. Jun 2014, 16:39

Re: 2d Array Ebene 2 drehen?

Beitrag von laz847 »

Danke Michi aber warum so kompliziert? Wenn tmpArray weiterhin verfügbar wäre, könnte ich doch auch direkt auf tmpArray[length(tmpArray)-1-pos] zugreifen ;) ???

Bei pos 0 wäre das Ende des Array -> also der aktuellste Wert.
Eine weitere Möglichkeit, Daten in einer Liste zu speichern, sind die so genannten verketteten Listen. Eine solche Liste besteht aus Elementen, die jeweils aus einem Pointer auf einen Datenbereich und einem Pointer auf das nächste Element in der Liste bestehen. Die Elemente können beliebig im Speicher verteilt sein. Sie müssen also nicht hintereinander liegen. Diese Listen haben den Vorteil, dass das Verschieben, Löschen und Abhängen von Daten recht schnell geht. Dafür ist der Zugriff auf ein bestimmtes Element sehr langsam.
Genau die Vorteile einer Liste brauche ich nicht, ich muss weder LÖSCHEN noch EINFÜGEN oder VERSCHIEBEN.

Nur einmal ERSTELLEN und DREHEN und dann brauche ich schnellen Zugriff auf einzelne Elemente.

Evtl. könnte ich beim ERSTELLEN eine Liste verwenden, das QuellArray wird aktuell dynamisch pro Element vergössert, da könnte noch etwas rauszuholen sein.

Michl
Beiträge: 2511
Registriert: Di 19. Jun 2012, 12:54

Re: 2d Array Ebene 2 drehen?

Beitrag von Michl »

...nur halb gelesen, wenn tmpArray nicht mehr da ist, ists nicht gut. Das Kopieren hätte man gespart (oder als Block kopiert) und wenn man nur sporadisch Werte aus dem Array benötigt hätte und das Record nicht nur aus vier Floats bestanden hätte, wärs eine Möglichkeit gewesen.

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection;  

laz847
Beiträge: 114
Registriert: Mi 18. Jun 2014, 16:39

Re: 2d Array Ebene 2 drehen?

Beitrag von laz847 »

Jup, aber da ich die Werte auch noch später und für weitere Währungen / pro Bar(Kerze) benötige, hätte ich anstatt meinem cache 3d Array dann ein 3d tmpArray :D . Also das selbe in Grün, nur drehen muss ich die Daten trotzdem, tmpArray ist < wie es heißt nur > ein temporäres Array.

Ob ich die Daten im TmpArray oder einer Liste erstelle und dann gespiegelt in das CacheArray übertrage macht vom Ablauf her keinen Unterschied.

By the way, wenn ich eine befüllte Liste nicht mehr benötige, reicht .Free oder muss ich jedes einzelne Element mit Dispose bearbeiten???

Antworten