Minimalwertspeicher für Messwerte

OP #8013806
Lesenswert?

Hallo, ich möchte eine Logik programmieren, die aus einem Datenstrom mit Messwerten die beiden kleinsten Werte speichert. Wenn der kleinste Messwert zwei mal im Datenstrom kommt, dann sollen beide Speicher diesen Wert erhalten:

Würde das so gehen ?

1
Init:   I_d_min1[i]  = 100;     // Minimalwertspeicher initialisieren
2
        I_d_min2[i]  = 100;
3
     
4
        
5
Loop:        
6
        // I_d[i] = aktueller Messwert
7
        // I_d_min1[i]    Minimalwertspeicher 1
8
        // I_d_min2[i]    Minimalwertspeicher 2
9
        
10
        // Wenn aktueller Wert kleiner als die beiden Speicher ist
11
        if ((I_d[i] < I_d_min1[i]) && (I_d[i] < I_d_min2[i]) )  
12
            {
13
            // Wenn Speicher1 > Speicher 2 
14
            if (I_d_min1[i] > I_d_min2[i])
15
               //dann Speicher 1 überschreiben 
16
               I_d_min1[i] = I_d[i];
17
            else
18
               //sonst Speicher 2 überschreiben 
19
               I_d_min2[i] = I_d[i];   
20
            }
21
        
22
        else 
23
            {
24
             // Wenn aktueller Wert kleiner Speicher 1 und größer Speicher2
25
            if ((I_d[i] < I_d_min1[i]) && (I_d[i] > I_d_min2[i]) )  
26
                // dann Speicher 1 überschreiben
27
                 I_d_min1[i] = I_d[i]; 
28
            // Wenn aktueller Wert kleiner Speicher 2 und größer Speicher1
29
            if ((I_d[i] < I_d_min2[i]) && (I_d[i] > I_d_min1[i]) )  
30
                // dann Speicher 2 überschreiben
31
                 I_d_min2[i] = I_d[i]; 
32
            }
: Bearbeitet durch User
#8013816
Lesenswert?

Norbert schrieb:

Wenn man sich seine Wünsche und Anforderungen in reiner Textform aufschreibt ...

Ja, nee. Die Textaufgabe muss man dann als erstes wieder als übersichtliche logische Struktur darstellen, z.B. in Form eines Nassi-Shneiderman-Diagramms. Dort sieht man relativ klar, ob man alle Fälle abgedeckt hat und kann das dann ziemlich direkt in Programmcode umsetzen. Bevor man sich an den eigentlichen Programmcode macht, sollte man die Testszenarien klar formulieren, so dass man vollständige Tests für den Code vorliegen hat, bevor die erste Programmzeile für das eigentliche Programm im Editor landet.

: Bearbeitet durch User
#8013872
Lesenswert?

Norbert schrieb:

Insbesondere für so komplexe Aufgaben wie die Ermittlung zweier MIN Werte. ;-)

Wenn ich den Umfang des oben gezeigten Programmcodes sehe, sind solche grundlegenden Überlegungen, egal wie einfach das Problem ist, hier nicht fehl am Platz und offenbaren dann schnell mögliche Vereinfachungen.

: Bearbeitet durch User
#8013893
Lesenswert?

In anderen Worten: Deine Lösung ist falsch und zu komplex. Zudem in einer unbekannten Pseudosprache, die vielleicht Sinn macht, in z.B. C aber nicht. Pseudocode ist zwar OK, aber x[i] sollte die Bedeutung eines Arrays haben, während spezielle Werte z.B. x_min heißen sollten.

Der übliche Weg wäre für mich: Ein Papier und ein paar Kritzeleien. Je weniger vertraut Du damit bist, umso mehr echte Worte/Gleichungen/Pseudocode sind notwendig.

#8013898
Lesenswert?

Eine schöne Aufgabe für eine Ruby Goldberg Min Min Machine…

1
#!python
2
#!/usr/bin/python3
3
# vim: fileencoding=utf-8: ts=4: sw=4: expandtab:
4

5
def RGMMM():    # Ruby Goldberg Min Min Machine
6
    min1,min2 = 100,100
7
    def inner(x):
8
        nonlocal min1,min2
9
        if x < min1:
10
            min1 = x
11
            if min1 < min2:
12
                min1,min2 = min2,min1
13
        return min2,min1
14
    return inner
15

16
rgmmm = RGMMM()
17
for x in range(5,-1,-1):
18
    print(rgmmm(x))
19

20
rgmmm = RGMMM()
21
for x in range(3):
22
    print(rgmmm(x))
23

24
rgmmm = RGMMM()
25
print(rgmmm(9))
26
print(rgmmm(6))
27
print(rgmmm(7))
28
print(rgmmm(8))
29
print(rgmmm(2))
30
print(rgmmm(2))
OP #8013901
Lesenswert?

Hallo, danke für die vielen Hinweise, besonders von Rainer W. Hier die vereinfachte Version::

1
    void Minimalwerte (int *aktuell, int *Speicher1, int *Speicher2 )
2
        {
3
        // Minimalwertspeicher zwei tiefsen Werte
4
        // Speicher1 = tiefster Wert
5
        // Speicher2 = zweit tiefster Wert
6
        
7
        if (aktuell < Speicher1)  
8
            {
9
            Speicher1 = aktuell;
10
            return;
11
            }
12
 
13
        if (aktuell < Speicher2  && aktuell >= Speicher1  )  
14
            {
15
            Speicher2 = aktuell;
16
            }
17
        }  // End function
#8013918
Lesenswert?

Dirk F. schrieb:

Hier die vereinfachte Version:: ...

if (aktuell < Speicher1) {... return;} ... if (aktuell < Speicher2 && aktuell >= Speicher1 )

Du vergleichst immer noch ein Mal zu viel. Wenn beim ersten Vergleich die Bedingung nicht erfüllt ist, d.h.

1
aktuell >= Speicher1

ist, musst du das beim zweiten Vergleich nicht noch einmal prüfen.

: Bearbeitet durch User
#8013968
Lesenswert?

1
void mw (int x, int *m1, int *m2 )
2
{
3
    if (x < *m2)  
4
    {
5
        if(x < *m1) {*m2 = *m1; m1 = x;}
6
        else        {*m2 =           x;}
7
    }
8
}

Zum Verständnis sind wie in der Mathematik kurze Namen besser. Im späteren Code reduzieren längere Namen die Beschreibung.

: Bearbeitet durch User
OP #8014025
Lesenswert?

Danke Bruno und Rainer.

Diese Version ist getestet und läuft:

1
    void Minimalwerte (int *aktuell, int *Speicher1, int *Speicher2 )
2
        {
3
        // Minimalwertspeicher zwei tiefsen Werte
4
        // Speicher1 = tiefster Wert
5
        // Speicher2 = zweit tiefster Wert
6
        
7
        if (*aktuell < *Speicher1)  
8
            {
9
            *Speicher2 = *Speicher1;
10
            *Speicher1 = *aktuell;
11
            return;
12
            }
13
 
14
        if (*aktuell < *Speicher2  && *aktuell >= *Speicher1  )  
15
            {
16
            *Speicher2 = *aktuell;
17
            }
18
        }  // End function
#8014384
Lesenswert?

Dirk F. schrieb:

Aber bei 200 MHz Prozessor und 2 MB Flash, 50 us Zykluszeit........... was solls....

Welche Bedeutung solche Optimierung im Algorithmus hat, hängt immer davon ab, ob die Optimierung im Compiler solchen redundanten Code noch erkennen und rausschmeißen kann und welchen Anteil der Code an der Prozessorauslastung trägt. Wenn der zu 99% mit leeren Schleifen beschäftigt ist, spielt es natürlich keine Rolle. Dann ist es nur schade um die vergeudeten Resourcen.

Die Struktur deines Codes mit dem doppelten Ausgang aus der Funktion lässt diese Doppelabfrage sowieso nicht erkennen. Besser lesbar wäre, wenn die zweite Abfrage im else-Zweig der ersten stände und das 'return' nicht mitten drin.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren