W
PiotreD schrieb:
hi..also, ich habe versucht deinen code zu verstehen, nur leider bin ich nicht so gut. könntest du mir nochmal erklären, was die einzelnen abschnitte so machen.
Also noch mal im einzelnen:
int main()
{
using namespace std;
const double arr[] = { 3.1, 9.6, 3.3, -90.7, 3.3, 3.1 };
cout << "Mittelwert: " << mittelwert( arr, arr + sizeof(arr)/sizeof(*arr), 2.0 ) << endl;
return 0;
}
da ist ein Array 'arr' mit doubles. An die Funktion 'mittelwert' wird der Zeiger auf das erste (arr) und letze (arr + sizeof(arr)/sizeof(*arr)) und eine Toleranz von 2.0 übergeben.
Anschließend wird das, was die Funktion mittelwert zurückliefert, ausgegeben.
template< typename InItr >
double mittelwert( InItr von, InItr bis, double tol )
{
das ist Template, d.h man kann hier einen beliebigen Typen einsetzen, der (in diesem Fall) alle Anforderungen nach einem Input-Iterator erfüllt. In diesem konkreten Fall könnte man auch 'const double*' statt InItr schreiben und die Zeile mit 'template' weglassen.
using namespace std;
list< double > werte( von, bis );
hier werden jetzt zuerst alle Werte in eine Liste mit Namen 'werte' kopiert. Ich benutzte deshalb eine Liste, da ich dann sehr effizient Elemente, die mitten drin stehen, daraus wieder löschen kann.
double mittelwert = accumulate( werte.begin(), werte.end(), 0.0 ) / werte.size();
mit dem Algorithmus 'accumulate' werden alle Werte der Liste zusammengezählt und anschließend wird das Ergebnis durch die Anzahl der Elemente (werte.size()) geteilt. Damit erhält man den Mittelwert aus allen (!) Werte.
for( list< double >::iterator i
; i = max_element( werte.begin(), werte.end(), AbstandZu( mittelwert ) ), std::abs( *i - mittelwert ) > tol; )
{
Hier wird jetzt mit dem Algorithmus max_element, dasjenige Element gesucht, das am weitesten vom Mittelwert entfernt ist. Als Ergebnis bekommt man einen Iterator 'i', der auf eben dieses Element zeigt. Gleich anschließend wird geschaut, ob der absolute Abstand zum Mittelwert größer als 'tol' ist. Falls nein, wird die for-Schleife abgebrochen.
Falls ja ...
mittelwert = (mittelwert * werte.size() - *i) / (werte.size() - 1); // neuen Mittelwert ohne *i
// cout << "Loesche " << *i << endl;
werte.erase( i );
}
return mittelwert;
}
... wird ein neuer Mittelwert ohne dieses am weitesten entfernte Element '*i' berechnet und das Element aus der Liste entfernt.
Danach wird durch die for-Schleife wieder das am weitest entfernte Element aus den noch verbliebenen Elementen gesucht - usw. (s.o.)
Bei Abbruch der Schleife wird der aktuelle Mittelwert zurückgegeben.
Wenn man das 'cout << ' auskommentiert erhält man als Ausgabe:
Loesche -90.7
Loesche 9.6
Mittelwert: 3.2
PiotreD schrieb:
habe wohl verstanden, dass mir das programm sozusagen nur die werte nimmt, die innerhalb der toleranz von 2.0 liegen.
korrekt
PiotreD schrieb:
ist das jetzt so: ich bilde einen mittelwert über wieviele werte?
beim ersten Mal über alle
PiotreD schrieb:
anschließend vergleiche ich den mittelwert mit dem nächste wert. falls dieser >2 ist, dann wird er nicht berücksichtigt und gelöscht.
nein nicht mit dem nächsten Wert, sondern es wird der Wert von allen noch verbliebenen gesucht, der am weitesten vom Mittelwert entfernt ist. Und dieser wird dann gelöscht, falls der Abstand größer 'tol' (hier ==2.0) ist.
PiotreD schrieb:
kann ich mir auch ausgeben lassen, wo sozusagen die grenze ist, d.h wann der mittelwert nicht mehr mit dem nächsten wert übereinstimmt?
müßte ja in eine variable einbringen. sozusagen dass ich 2werte bekomme:einmal von links und einmal von rechts. geht dies?
Hier versteh ich die Frage nicht. Kannst Du mal ein Zahlenbeispiel bringen, und an Hand dieses Zahlenbeispiels nochmal fragen.
Gruß
Werner