Puffer bzw. Datenstruktur für 1000 Integerwerte

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
Antworten
oliver2104
Beiträge: 22
Registriert: Sa 26. Dez 2020, 13:22

Puffer bzw. Datenstruktur für 1000 Integerwerte

Beitrag von oliver2104 »

Hallo, bei mir kommen über die serielle Schnittstelle ständig Integerwerte rein.
Brauch aber nur Zugriff auf die letzten 1000 Werte, zb: wert[0] - wert[999]

wenn ein neuer Wert reinkommt soll der auf wert[999] gespeichert werden.
vorher muss aber noch: wert[0]:= wert[1]; wert[1]:= wert[2]; usw bis wert[998]:= wert[999] passieren.
d.h. alte werte fallen vorne raus, neue werte kommen hinten rein.

Dazu fällt mir nur ein eindimensiales Integerarray ein.
Und die Werte mit einer FOR Schleife verschieben.
Würdet ihr das auch so machen oder gäbe es da eine elegantere Lösung z.b. mit Zeigern ?

Benutzeravatar
theo
Beiträge: 10500
Registriert: Mo 11. Sep 2006, 19:01

Re: Puffer bzw. Datenstruktur für 1000 Integerwerte

Beitrag von theo »

Vielleicht mit TQueue?
https://www.freepascal.org/docs-html/fc ... queue.html

Oder mit Generics:

Code: Alles auswählen

unit Unit1;

{$mode delphi}{$H+}

interface

uses
  Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls,
  Generics.Collections;

type

  { TForm1 }

  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private

  public

  end;

var
  Form1: TForm1;

  Queue: TQueue<integer>;

implementation

{$R *.lfm}

{ TForm1 }

procedure TForm1.Button1Click(Sender: TObject);
begin
  Queue := TQueue<integer>.Create;
  Queue.Enqueue(23);
  Queue.Enqueue(24);
  Queue.Enqueue(25);
  ShowMessage(IntToStr(Queue.Dequeue));
  ShowMessage(IntToStr(Queue.Dequeue));
  Queue.Free;
end;

end.  

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6216
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: Puffer bzw. Datenstruktur für 1000 Integerwerte

Beitrag von af0815 »

Dazu fällt mir der Begriff Ringpuffer ein. Der arbeitet mit einem Array und zwei Zeigern. Der eine Zeiger ist der Schreibzeiger und der andere der Lesezeiger. Ganz einfache Regeln, wenn die Zeiger das Ende der Array erreicht haben, werden sie auf den Anfang zurück gebracht. Der Lesezeiger darf den Schreibzeiger niemals überholen, ist Lesezeiger gleich Schreibzeiger ist der Puffer leer. Zurück gehen geht auch, man muss nur bedenken, das erst nach der ersten Runde der Puffer gefüllt ist und sich das merken. Vorteil, es wird nichts umkopiert, sondern nur Zeiger versetzt.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

oliver2104
Beiträge: 22
Registriert: Sa 26. Dez 2020, 13:22

Re: Puffer bzw. Datenstruktur für 1000 Integerwerte

Beitrag von oliver2104 »

Danke für eure Tips,
Werde mir beides genau anschauen.
Bitte nicht sofort mit einer Antwort rechnen.
Bin nicht der schnellste.
Wünsch euch schöne Feiertage

Freako123
Beiträge: 1
Registriert: Fr 29. Dez 2023, 12:05

Re: Puffer bzw. Datenstruktur für 1000 Integerwerte

Beitrag von Freako123 »

Hallo Oliver2104,

deine Idee mit einem eindimensionalen Integerarray und einer FOR-Schleife ist grundsätzlich eine einfache und funktionale Möglichkeit, die letzten 1000 Integerwerte zu speichern. Wenn du jedoch nach einer möglicherweise eleganteren Lösung als selbstständiger Data Analyst suchst, könntest du auch mit einem Ringpuffer (Circular Buffer) arbeiten. Ein Ringpuffer ist eine Datenstruktur, bei der die Daten zyklisch gespeichert werden, sodass keine Verschiebung der Elemente erforderlich ist.

Hier ist ein einfaches Beispiel in Pseudocode für einen Ringpuffer:

python
Copy code
class RingBuffer:
def __init__(self, size):
self.size = size
self.buffer = [0] * size
self.head = 0 # Zeiger auf das älteste Element
self.tail = 0 # Zeiger auf das nächste freie Element

def push(self, value):
self.buffer[self.tail] = value
self.tail = (self.tail + 1) % self.size
if self.tail == self.head:
self.head = (self.head + 1) % self.size # Falls der Puffer voll ist, überschreibe das älteste Element

def get_values(self):
if self.head <= self.tail:
return self.buffer[self.head:self.tail]
else:
return self.buffer[self.head:] + self.buffer[:self.tail]

# Beispiel-Nutzung:
buffer = RingBuffer(1000)

# Serielle Werte empfangen und in den Puffer legen
while neue_werte_empfangen:
neuer_wert = serielle_schnittstelle.lese_wert()
buffer.push(neuer_wert)

# Zugriff auf die letzten 1000 Werte
letzte_1000_werte = buffer.get_values()
Mit einem Ringpuffer kannst du die ältesten Werte einfach "vergessen", wenn neue Werte hinzukommen, ohne eine aufwändige Verschiebung der Elemente durchführen zu müssen. Beachte, dass dies nur ein einfaches Beispiel ist, und du es an deine spezifischen Anforderungen anpassen musst.
Zuletzt geändert von Freako123 am Mi 31. Jan 2024, 03:20, insgesamt 1-mal geändert.
Ich bin Rene

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6216
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: Puffer bzw. Datenstruktur für 1000 Integerwerte

Beitrag von af0815 »

BTW. wir sind ein Pascalforum und man sollte auch Codetags verwenden, bitte das auch beim ersten Post bedenken freako123. Vor allen wenn im Codeschnipsel "Copy code" drinnensteht kommt mir das schon sehr trollig vor.

Das mit dem Rinpuffer habe ich bereits ein paar Posts vorher geschrieben und vergessen braucht man die alten Werte nicht, man kann den Puffer auch zurückgehen, wenn man die Abbruchbedingungen einhält. Das für statistische Zwecke durchaus normal sein.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

Antworten