Minimum/Maximum einer Reihe von Werten bestimmen

Für allgemeine Fragen zur Programmierung mit PureBasic.
Benutzeravatar
jacdelad
Beiträge: 341
Registriert: 03.02.2021 13:39
Computerausstattung: Ryzen 5800X, 108TB Festplatte, 32GB RAM, Radeon 7770OC
Wohnort: Riesa
Kontaktdaten:

Minimum/Maximum einer Reihe von Werten bestimmen

Beitrag von jacdelad »

Ich hab ein paar Koordinaten (4 an der Zahl), von denen jeweils die Minimum-/Maximum-Werte bestimmt werden sollen:

Code: Alles auswählen

Structure Rechteck
  left.l
  right.l
  top.l
  bottom.l
EndStructure
Define a.POINT,b.POINT,c.POINT,d.POINT,max.Rechteck

;Schleife
;Koordinatenermittlung
  If a\x<max\left:max\left=a\x:ElseIf a\x>max\right:max\right=a\x:EndIf
  If b\x<max\left:max\left=b\x:ElseIf b\x>max\right:max\right=b\x:EndIf
  If c\x<max\left:max\left=c\x:ElseIf c\x>max\right:max\right=c\x:EndIf
  If d\x<max\left:max\left=d\x:ElseIf d\x>max\right:max\right=d\x:EndIf
  If a\y<max\top:max\top=a\y:ElseIf a\y>max\bottom:max\bottom=a\y:EndIf
  If b\y<max\top:max\top=b\y:ElseIf b\y>max\bottom:max\bottom=b\y:EndIf
  If c\y<max\top:max\top=c\y:ElseIf c\y>max\bottom:max\bottom=c\y:EndIf
  If d\y<max\top:max\top=d\y:ElseIf d\y>max\bottom:max\bottom=d\y:EndIf
;Schleife Ende
;Weiterverarbeitung
Gibt es da vielleicht eine effizientere Möglichkeit?
PureBasic 6.04/XProfan X4a/Embarcadero RAD Studio 11/Perl 5.2/Python 3.10
Windows 11/Ryzen 5800X/32GB RAM/Radeon 7770 OC/3TB SSD/11TB HDD
Synology DS1821+/36GB RAM/130TB
Synology DS920+/20GB RAM/54TB
Synology DS916+ii/8GB RAM/12TB
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 6996
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: Minimum/Maximum einer Reihe von Werten bestimmen

Beitrag von STARGÅTE »

Schreib dir noch einfach eine Min und Max Funktion mit 4 Parametern, dann kannst du ja dein "max" wie folgt ausrechnen:

Code: Alles auswählen

max\left = Min(a\x, b\x, c\x, d\x)
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Benutzeravatar
jacdelad
Beiträge: 341
Registriert: 03.02.2021 13:39
Computerausstattung: Ryzen 5800X, 108TB Festplatte, 32GB RAM, Radeon 7770OC
Wohnort: Riesa
Kontaktdaten:

Re: Minimum/Maximum einer Reihe von Werten bestimmen

Beitrag von jacdelad »

Ja, das habe ich auch schon überlegt, aber schneller ist das nicht.
PureBasic 6.04/XProfan X4a/Embarcadero RAD Studio 11/Perl 5.2/Python 3.10
Windows 11/Ryzen 5800X/32GB RAM/Radeon 7770 OC/3TB SSD/11TB HDD
Synology DS1821+/36GB RAM/130TB
Synology DS920+/20GB RAM/54TB
Synology DS916+ii/8GB RAM/12TB
GPI
Beiträge: 1511
Registriert: 29.08.2004 13:18
Kontaktdaten:

Re: Minimum/Maximum einer Reihe von Werten bestimmen

Beitrag von GPI »

ein Macro könnte das einfacher zum schreiben machen.

Code: Alles auswählen

Macro SetMax(_a_,_max_)
  If _a_\x < _max_\left : _max_\left = _a_\x : ElseIf _a_\x > _max_\right : _max_\right = _a_\x : EndIf
  If _a_\y < _max_\top : _max_\top = _a_\y : ElseIf _a_\y > _max_\bottom : _max_\bottom = _a_\y : EndIf
Endmacro

; Beim ersten mal nicht das Macro setzen, sondern direkt die werte! Der Punkt ist ja aktuell der kleinste *UND* größte Punkt!
max\left = a\x : max\right = a\x
max\top = a\y : max\bottom = a\y
; die restlichen einfach überprüfen lassen.
SetMax(b,max)
SetMax(c,max)
SetMax(d,max)
schneller ist es nicht, aber auch nicht langsamer, dafür aber besser lesbar und damit wartbar.

Wenns wirklich nur 4 Werte sind, dann kannst du folgendes probieren:

Code: Alles auswählen

IF a/x < b/x
  IF c/x < d /x
    ;a und c sind kleinste
    IF a/x < c/x
      max\left = a/x
    else
      max\left= c/x
    endif
    ; und gleichzeitig B und D die größten
    IF b/x > d/x
      max\right = b/x
    else
      max\right = d/x
    endif
  else
    ;a und d sind die kleinsten
    IF a/x < d/x
      max\left = a/x
    else
      max\left = d/x
    endif
    ; und gleichzeitig B und c die größten
    IF b/x > c/x
      max\right = b/x
    else
      max\right = c/x
    endif
  endif
else
   IF c/x < d /x
    ;b und c sind kleinste
    IF b/x < c/x
      max/left = b/x
    else
      max/left = c/x
    endif
    ; und gleichzeitig a und D die größten
    IF a/x > d/x
      max\right = a/x
    else
      max\right = d/x
    endif
  else
    ;b und d sind die kleinsten
    IF b/x < d/x
      max\left = b/x
    else
      max\left = d/x
    endif
    ; und gleichzeitig a und c die größten
    IF a/x > c/x
      max\right = a/x
    else
      max\right = c/x
    endif
  endif
endif
DAS ist aber dann schlecht wartbar! Reduziert aber die IF-Abfragen auf ein minium und auch das setzen der max variable. Würd ich aber nur machen, wenn du wirklich viele 4er-Punkte so abarbeiten musst.
Falls du ein Absolutes Max über viele 4er-Punkte willst, musst du an den Stellen, wo MAX\Left und MAX\Right gesetzt werden, noch überprüfen, ob das alte MAX\LEFT / Max\Right überhaupt kleiner ist als der ermittelte Punkt. Für TOP/BOT gehts analog.
Könntest auch ein Macro machen, indem du dann die Structure-Felder angibst.

Code: Alles auswählen

macro Check( _xy_, _lefttop_, rightbottom_)
IF a/_xy_ < b/_xy_
  IF c/_xy_ < d /_xy_
    ;a und c sind kleinste
    IF a/_xy_ < c/_xy_
      max\_lefttop_ = a/_xy_
  [...] usw. [...]
endmacro

check(x, left, right)
check(y, top, bottom)

Und setz kommentare - das hilft bei späteren Warten ungemein :)
CodeArchiv Rebirth: Deutsches Forum Github Hilfe ist immer gern gesehen!
GPI
Beiträge: 1511
Registriert: 29.08.2004 13:18
Kontaktdaten:

Re: Minimum/Maximum einer Reihe von Werten bestimmen

Beitrag von GPI »

oder ums allgemeiner zu halten:

Code: Alles auswählen

EnableExplicit
Macro GetMinMax(_a_,_b_,_c_,_d_,_min_,_max_)
  If _a_ < _b_
    If _c_ < _d_ 
      ;a und c sind die kleinsten
      If _a_ < _c_
        _min_ = _a_
      Else
        _min_= _c_
      EndIf
      ; und gleichzeitig B und D die größten
      If _b_ > _d_
        _max_ = _b_
      Else
        _max_ = _d_
      EndIf
    Else
      ;a und d sind die kleinsten
      If _a_ < _d_
        _min_ = _a_
      Else
        _min_ = _d_
      EndIf
      ; und gleichzeitig B und c die größten
      If _b_ > _c_
        _max_ = _b_
      Else
        _max_ = _c_
      EndIf
    EndIf
  Else
    If _c_ < _d_ 
      ;b und c sind die kleinsten
      If _b_ < _c_
        _min_ = _b_
      Else
        _min_ = _c_
      EndIf
      ; und gleichzeitig a und D die größten
      If _a_ > _d_
        _max_ = _a_
      Else
        _max_ = _d_
      EndIf
    Else
      ;b und d sind die kleinsten
      If _b_ < _d_
        _min_ = _b_
      Else
        _min_ = _d_
      EndIf
      ; und gleichzeitig a und c die größten
      If _a_ > _c_
        _max_ = _a_
      Else
        _max_ = _c_
      EndIf
    EndIf
  EndIf
EndMacro

Define.point a,b,c,d
Define.rect max

a\x = Random(1000)-500
a\y = Random(1000)-500
b\x = Random(1000)-500
b\y = Random(1000)-500
c\x = Random(1000)-500
c\y = Random(1000)-500
d\x = Random(1000)-500
d\y = Random(1000)-500

Debug ""+a\x+" "+a\y
Debug ""+b\x+" "+b\y
Debug ""+c\x+" "+c\y
Debug ""+d\x+" "+d\y

Debug" ---- "
GetMinMax(a\x, b\x, c\x, d\x, max\left, max\right)
GetMinMax(a\y, b\y, c\y, d\y, max\top, max\bottom)
Debug ""+max\left+" - "+max\right+" x "+max\top+" - "+max\bottom
bitte beachten, das ist ein Macro.
ein "GetMaxMin( a+b, c+d, e+f, min, max)" würde funktionieren, aber überall wo ein "_a_" steht würde dann "a+b" stehen und es würden x unnötige Additionen erfolgen. Ansonsten ist das Maco jetzt universell anwendbar. Würde bspw. auch mit Strings funktionieren!
CodeArchiv Rebirth: Deutsches Forum Github Hilfe ist immer gern gesehen!
Benutzeravatar
jacdelad
Beiträge: 341
Registriert: 03.02.2021 13:39
Computerausstattung: Ryzen 5800X, 108TB Festplatte, 32GB RAM, Radeon 7770OC
Wohnort: Riesa
Kontaktdaten:

Re: Minimum/Maximum einer Reihe von Werten bestimmen

Beitrag von jacdelad »

Danke für die Ansätze, aber das macht's nicht wirklich schneller oder effizienter und nur bedingt lesbarer. Aber das ist auch nicht schlimm, dann bleibt es wie es ist.
PureBasic 6.04/XProfan X4a/Embarcadero RAD Studio 11/Perl 5.2/Python 3.10
Windows 11/Ryzen 5800X/32GB RAM/Radeon 7770 OC/3TB SSD/11TB HDD
Synology DS1821+/36GB RAM/130TB
Synology DS920+/20GB RAM/54TB
Synology DS916+ii/8GB RAM/12TB
Antworten