Größter Wert eines Arrays

Eigentlich ist mir die Frage peinlich, aber es kann sonst niemand helfen ... :)

Moderator: Moderatoren

Antworten
stevie
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 417
Registriert: Mo, 17. Sep 2007 18:20
Wohnort: Senftenberg
Kontaktdaten:

Größter Wert eines Arrays

Beitrag von stevie »

Wie finde ich den größten Wert in einem Array?
aarray:={1,6,8,19,8,20,6}
Es können Werte doppelt vor kommen. max() wäre ein Ansatz, das ließ sich aber noch nicht richtig verbinden.
Benutzeravatar
Martin Altmann
Foren-Administrator
Foren-Administrator
Beiträge: 16502
Registriert: Fr, 23. Sep 2005 4:58
Wohnort: Berlin
Hat sich bedankt: 111 Mal
Danksagung erhalten: 48 Mal
Kontaktdaten:

Beitrag von Martin Altmann »

Hallo Stevie,
vielleicht so?

Code: Alles auswählen

nMax := -890
aarray:={1,6,8,19,8,20,6}
aEval( aarray, {|x| iif( x > nMax, nMax := x, ) } )
? nMax
Viele Grüße,
Martin
:grommit:
Webseite mit XB2.NET und ausschließlich statischem Content in Form von HTML-Dateien: https://www.altem.de/
Webseite mit XB2.NET und ausschließlich dynamischem Content in Form von in-memory-HTML: https://meldungen.altem.de/

Mitglied der XUG Osnabrück
Vorsitzender des Deutschsprachige Xbase-Entwickler e. V.
stevie
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 417
Registriert: Mo, 17. Sep 2007 18:20
Wohnort: Senftenberg
Kontaktdaten:

Beitrag von stevie »

Martin Altmann hat geschrieben:Hallo Stevie,
vielleicht so?

Code: Alles auswählen

nMax := -890
aarray:={1,6,8,19,8,20,6}
aEval( aarray, {|x| iif( x > nMax, nMax := x, ) } )
? nMax
Viele Grüße,
Martin
Hab ne einfachere Methode gefunden.
aachs ist das Zahlenarray.
czeit:=max(0,aachs[1])
for i:=2 to lastrec()
czeit:=max(czeit,aachs)
next
Benutzeravatar
Martin Altmann
Foren-Administrator
Foren-Administrator
Beiträge: 16502
Registriert: Fr, 23. Sep 2005 4:58
Wohnort: Berlin
Hat sich bedankt: 111 Mal
Danksagung erhalten: 48 Mal
Kontaktdaten:

Beitrag von Martin Altmann »

Hallo Stevie,
ist nicht einfacher, sondern das gleiche :-)

Viele Grüße,
Martin
:grommit:
Webseite mit XB2.NET und ausschließlich statischem Content in Form von HTML-Dateien: https://www.altem.de/
Webseite mit XB2.NET und ausschließlich dynamischem Content in Form von in-memory-HTML: https://meldungen.altem.de/

Mitglied der XUG Osnabrück
Vorsitzender des Deutschsprachige Xbase-Entwickler e. V.
stevie
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 417
Registriert: Mo, 17. Sep 2007 18:20
Wohnort: Senftenberg
Kontaktdaten:

Beitrag von stevie »

Martin Altmann hat geschrieben:Hallo Stevie,
ist nicht einfacher, sondern das gleiche :-)

Viele Grüße,
Martin
benötigt aber weniger Code.
In den Datenbrowser hab ich nämlich noch ein Gehe zu eingebaut und damit der User weiß, in welchem Rahmen er eintragen darf, berechne ich damit die Maximalgröße und gebe sie in () neben dem Editfeld aus.
Benutzeravatar
Martin Altmann
Foren-Administrator
Foren-Administrator
Beiträge: 16502
Registriert: Fr, 23. Sep 2005 4:58
Wohnort: Berlin
Hat sich bedankt: 111 Mal
Danksagung erhalten: 48 Mal
Kontaktdaten:

Beitrag von Martin Altmann »

Hm,
bei Dir sind es vier Zeilen und bei mir 2 (wenn ich die Ausgabe des Ergebnisses und die Initialisierung des Arrays weglasse, die es bei Deinem Beispiel auch nicht gab)... :wink:

Viele Grüße,
Martin
:grommit:
Webseite mit XB2.NET und ausschließlich statischem Content in Form von HTML-Dateien: https://www.altem.de/
Webseite mit XB2.NET und ausschließlich dynamischem Content in Form von in-memory-HTML: https://meldungen.altem.de/

Mitglied der XUG Osnabrück
Vorsitzender des Deutschsprachige Xbase-Entwickler e. V.
stevie
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 417
Registriert: Mo, 17. Sep 2007 18:20
Wohnort: Senftenberg
Kontaktdaten:

Beitrag von stevie »

Martin Altmann hat geschrieben:Hm,
bei Dir sind es vier Zeilen und bei mir 2 (wenn ich die Ausgabe des Ergebnisses und die Initialisierung des Arrays weglasse, die es bei Deinem Beispiel auch nicht gab)... :wink:

Viele Grüße,
Martin
okay ein paar Zeichen weniger,allerdings schlechter zu verstehen, jedenfalls für mich
Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 9345
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Hat sich bedankt: 100 Mal
Danksagung erhalten: 359 Mal
Kontaktdaten:

Beitrag von Tom »

Martins Variante geht auch (nach erfolgter Arrayinitialisierung) mit einer Zeile:

Code: Alles auswählen

aEval( aarray, {|x| iif( nMax = nil .or. x > nMax, nMax := x, ) } )
Herzlich,
Tom
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15689
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Beitrag von brandelh »

Hallo,

also wenn das Array nicht nur die 6 Elemente hat, ist der Code
mit FOR NEXT deutlich langsamer als mit AEVAL() - gleiches gilt für do while und DBEVAL().

Allerdings sind beide Methoden zu langsam um große Arrays abzuarbeiten. Hier gilt sortieren, dann steht der größte Wert im letzten bzw. ersten Feld. ASORT() ist dermaßen schnell, dass auch tausende von Arrayelementen keine Rolle spielen.
Gruß
Hubert
Benutzeravatar
Martin Altmann
Foren-Administrator
Foren-Administrator
Beiträge: 16502
Registriert: Fr, 23. Sep 2005 4:58
Wohnort: Berlin
Hat sich bedankt: 111 Mal
Danksagung erhalten: 48 Mal
Kontaktdaten:

Beitrag von Martin Altmann »

Hallo Stevie,
stevie hat geschrieben:...,allerdings schlechter zu verstehen, jedenfalls für mich
nun - das sieht nur auf den ersten Blick so aus, glaube mir!
Das aEval() macht nichts anderes, als Deine FOR...NEXT-Schleife:
  1. Der erste Parameter bei dem aEval ist das Array, das abgearbeitet werden soll.
  2. Der zweite Parameter ist der Codeblock, der auf jedes einzelne Element Deines Arrays angewandt wird:
    • Er enthält maximal zwei Parameter: Der erste ist das entsprechende Element des Arrays (in meinem Beispiel als x bezeichnet - dies entspricht in Deinem Beispiel dem aachs) und der zweite (den ich nicht genutzt habe) wäre der Zähler (auf dem wievielten Arrayelement man sich gerade befindet - also in Deinem Besipiel das i)
    • Als nächstes kommen innerhalb des Codeblocks die Anweisungen für jedes einzelne Element des Arrays - dort könnten auch mehrere Anweisungen stehen, die dann durch "," getrennt werden. In meinem Beispiel gibt es nur die IIF()-Funktion
  3. Die weiteren Parameter findest Du in der Hilfe erklärt - sie wurden hier nicht genutzt. Man kann noch mit angeben, ab dem wievielten Element des Arrays erst mit der Abarbeitung begonnen werden soll, wieviele Elemente von da an abgearbeitet werden sollen und ob das entsprechende Element im Array selber auch geändert werden darf.
Viele Grüße,
Martin
:grommit:
Webseite mit XB2.NET und ausschließlich statischem Content in Form von HTML-Dateien: https://www.altem.de/
Webseite mit XB2.NET und ausschließlich dynamischem Content in Form von in-memory-HTML: https://meldungen.altem.de/

Mitglied der XUG Osnabrück
Vorsitzender des Deutschsprachige Xbase-Entwickler e. V.
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15689
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Beitrag von brandelh »

Ich kann schon verstehen, warum einem eine 'schöne altmodische' FOR NEXT Schleife besser gefällt - oder übersichtlicher erscheint.
Geht mir manchmal auch so. Aber wenn man die unterschiedlichen Laufzeiten in einem größeren Programm sieht, kann es keine Frage mehr geben. Man muss dann einfach die komplexen Befehle oder Funktionen nutzen - offensichtlich sind die intern stark optimiert.
Gruß
Hubert
stevie
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 417
Registriert: Mo, 17. Sep 2007 18:20
Wohnort: Senftenberg
Kontaktdaten:

aEval

Beitrag von stevie »

Da wir gerade beim aEval waren..
::aMess:={}
aEval(::aSens,{|x| iif(x==1,aAdd(::aMess,x),.F.)})
Dieses aEval müsste mir eigentlich alle Werte aus ::aSens rausholen, die 1 sind und alle 1en in ::aMess schreiben. Alles zusammen läuft in einer Schleife in einer Methode. Wenn ich das kompilierte Programm starte,kommt die fiese Meldung:"Zugriff auf Membervariable verweigert" (::amess). Deklariert ist sie ordnungsgemäß als protected. Was stimmt da schon wieder nicht?
Sören
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 205
Registriert: Mo, 07. Aug 2006 10:18
Wohnort: Leipzig
Danksagung erhalten: 11 Mal

Beitrag von Sören »

Hallo Stevie,

Du musst die MemVars als EXPORTED deklarieren.

MemVars, die als PROTECTED deklariert sind, sind nur innerhalb des Programmcodes der Klasse und deren Sub-Klassen sichtbar.
Beste Grüße,
Sören
Robert
Cut&Paste-Entwickler
Cut&Paste-Entwickler
Beiträge: 36
Registriert: Mo, 13. Feb 2006 12:47

Re: aEval

Beitrag von Robert »

stevie hat geschrieben:"Zugriff auf Membervariable verweigert" (::amess). Deklariert ist sie ordnungsgemäß als protected.
Genau deshalb funktioniert es nicht. Durch die Ausführung des Codeblocks erfolgt der Zugriff auf ::aMess nicht mehr aus der Klasse selbst ( da ja Array, und der Codeblock an die Funktion aEval übergeben werden und dann innerhalb dieser Funktion auf ::aMess zugegriffen wird).

Das ist dann quasi in etwas so, als würdest du außerhalb deiner Klasse auf ::aMess zugreifen wollen. Das klappt ja auch nicht.

Du könntest eine neue Membervarialbe ::_aMess anlegen (protected oder hidden).

Für ::aMess machst du Assign und Accessmethoden:

EXPORTED:
ACCESS ASSIGN METHOD aMess

(Siehe ACCESS | ASSIGN in der xbase-Doku)

METHOD NameDeinerKlasse:aMess( aM )
// entsprechend vorher Prüfung, ob Daten auch korrekt sind
// ob es ein Array ist, nicht NIL, oder wie auch immer

::_aMess := aM

RETURN ::_aMess

Dadurch kannst du auf ::aMess ganz einfach zurgreifen. Gekapselt ist das ganze dennoch, da alles über die Methode geht, in der du steuern kannst, welche Daten gespeichert werden können.

Mit der Variante müsstest du nur neuen Code hinzufügen aber nichts am bestehenden ändern.

Vllt. geht das ja auch noch eleganter, aber so sollte es funktionieren
stevie
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 417
Registriert: Mo, 17. Sep 2007 18:20
Wohnort: Senftenberg
Kontaktdaten:

Re: aEval

Beitrag von stevie »

Robert hat geschrieben:
stevie hat geschrieben:"Zugriff auf Membervariable verweigert" (::amess). Deklariert ist sie ordnungsgemäß als protected.
Genau deshalb funktioniert es nicht. Durch die Ausführung des Codeblocks erfolgt der Zugriff auf ::aMess nicht mehr aus der Klasse selbst ( da ja Array, und der Codeblock an die Funktion aEval übergeben werden und dann innerhalb dieser Funktion auf ::aMess zugegriffen wird).

Das ist dann quasi in etwas so, als würdest du außerhalb deiner Klasse auf ::aMess zugreifen wollen. Das klappt ja auch nicht.

Du könntest eine neue Membervarialbe ::_aMess anlegen (protected oder hidden).

Für ::aMess machst du Assign und Accessmethoden:

EXPORTED:
ACCESS ASSIGN METHOD aMess

(Siehe ACCESS | ASSIGN in der xbase-Doku)

METHOD NameDeinerKlasse:aMess( aM )
// entsprechend vorher Prüfung, ob Daten auch korrekt sind
// ob es ein Array ist, nicht NIL, oder wie auch immer

::_aMess := aM

RETURN ::_aMess

Dadurch kannst du auf ::aMess ganz einfach zurgreifen. Gekapselt ist das ganze dennoch, da alles über die Methode geht, in der du steuern kannst, welche Daten gespeichert werden können.

Mit der Variante müsstest du nur neuen Code hinzufügen aber nichts am bestehenden ändern.

Vllt. geht das ja auch noch eleganter, aber so sollte es funktionieren
Die Variable zu exportieren ist dann doch einfacher,auch wenn niemand anders sie braucht.
Antworten