Position und Wert des Maximums eines Arrays
-
bin ein Matlabprogrammier, muss aber derzeit etwas in C++ implementieren. Habe ein Array von 512 double-Werten möchte möglichst schnell das Maximum finden, so wie dessen Position ausgeben. Das ganze soll ich als Funktion schreiben. Gibt es dort einen einfachen Befehl oder muss ich von Hand einen Such-Algo schreiben?
-
Wenn du viel Mathematisches programmierst, empfehle ich dir den Einsatz einer Mathematik-Bibliothek (Math Library). Die hat nicht nur viel mehr Features sondern auch meistens einen Datentyp mit dem es sich genau rechnen lässt.
Die C++-Standardbibliothek liefert dir für deinen konkreten Fall:
#include <algorithm> using namespace std; ... typedef std::vector<double> DoubleVector; ... DoubleVector myVector; // verwende keine arrays sondern nimm dafür container ... DoubleVector::iterator iter = max_element(myVector.begin(), myVector.end()); double max = *iter;
MfG SideWinder
-
einen eigenen befehl gibt es dafür nicht, vielleicht eine funktion aus der standartbibliothek.
oder mach es so:
unsigned pos = 0; double dmax = feld[0]; for (unsigned i = 0; i < 512; ++i) if (feld[i] > dmax) { max = feld[i]; pos = i; }
-
Dieser Thread wurde von Moderator/in SideWinder aus dem Forum DOS und Win32-Konsole in das Forum C++ verschoben.
Im Zweifelsfall bitte auch folgende Hinweise beachten:
C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?Dieses Posting wurde automatisch erzeugt.
-
helferlein schrieb:
einen eigenen befehl gibt es dafür nicht, vielleicht eine funktion aus der standartbibliothek.
oder mach es so:
unsigned pos = 0; double dmax = feld[0]; for (unsigned i = 0; i < 512; ++i) if (feld[i] > dmax) { max = feld[i]; pos = i; }
Das ist kein C++-Stil. Das sieht mir zu sehr nach C aus.
MfG SideWinder
-
helferlein schrieb:
einen eigenen befehl gibt es dafür nicht, vielleicht eine funktion aus der standartbibliothek.
oder mach es so:
unsigned pos = 0; double dmax = feld[0]; for (unsigned i = 0; i < 512; ++i) if (feld[i] > dmax) { max = feld[i]; pos = i; }
habe es so am laufen. Allerdings möchte ich es nun in einer funktion nutzen:
unsigned int arraymaximum(double feld[]){ unsigned pos = 0; double dmax = feld[0]; for (unsigned i = 0; i < sizeof(feld)/sizeof(double); i++) { if (feld[i] > dmax) { dmax = feld[i]; pos = i; } } return pos; }
Die Funktion will nicht, ich bekommen als ergebnis immer die initialisierte pos=0!?
-
template<typename Iterator> Iterator MaxValuePos(Iterator First, Iterator Last) { Iterator max = First++; for(;First != Last; ++First) { if(*First > *max) max = First; } return max; } int main() { int array[] = {6, 2, 1, 5, 8, 4, 3}; int* max = MaxValuePos(array, array+7); cout << *max << endl; // oder mit Containern vector<int> vec; // fill vec vector<int>::iterator max = MaxValuePos(vec.begin(), vec.end()); cout << *max << endl; }
-
Ein Standardproblem: Bei der Übergabe von Arrays gehen die Größeninformationen verloren. Lösung (1): Verwende das von SideWinder vorgeschlagene max_element, das funktioniert auch mit Arrays (wenn es denn unbedingt ein Array sein muss). Ergänzung (2): Schreibe Dir eine Templatefunktion, die die Größeninformation mit übernimmt.
(1):
size_t pos = distance( feld, max_element( feld, feld + sizeof(feld) / sizeof(*feld) ) );
(2):
template< typename T, size_t N > size_t max_element_n( T ( &array )[ N ] ) { return distance( array, max_element( array, array + N ) ); } size_t pos = max_element_n( feld );
Vorsicht ist bei (1) geboten: Wenn die Größeninformation bereits verloren ist, passiert hier derselbe Mist wie bei der ursprünglichen Funktion. Die Variante (2) hat hingegen den Vorteil, dass der Compiler bereits meckert, wenn N nicht mehr ermittelbar ist.
-
SideWinder schrieb:
Wenn du viel Mathematisches programmierst, empfehle ich dir den Einsatz einer Mathematik-Bibliothek (Math Library). Die hat nicht nur viel mehr Features sondern auch meistens einen Datentyp mit dem es sich genau rechnen lässt.
Die C++-Standardbibliothek liefert dir für deinen konkreten Fall:
#include <algorithm> using namespace std; ... typedef std::vector<double> DoubleVector; ... DoubleVector myVector; // verwende keine arrays sondern nimm dafür container ... DoubleVector::iterator iter = max_element(myVector.begin(), myVector.end()); double max = *iter;
MfG SideWinder
Danke. Kann ich denn mit dem Iterator auch direkt die Position des Maximums innerhalb des Vektors bestimmen?
-
elsucht schrieb:
Kann ich denn mit dem Iterator auch direkt die Position des Maximums innerhalb des Vektors bestimmen?
Ja - steht schon in LordJaxoms Beitrag (siehe (1): ):
size_t pos = distance( myVector.begin(), iter );
.. was in diesem Fall mit dem Vektor identisch zu
size_t pos = iter - myVector.begin();
ist
Gruß
Werner
-
helferlein schrieb:
unsigned pos = 0; double dmax = feld[0]; for (unsigned i = 0; i < 512; ++i) if (feld[i] > dmax) { max = feld[i]; pos = i; }
also ich bin eher ein c++ neuling aber ist die funktion so überhaupt korrekt? wenn ich das richtig sehe sucht die schleife doch nur den eintrag der größer ist als feld[0] also den 1. eintrag des feldes.. was ist denn nu wenn zb. feld[0]=12 ist feld[14]=36 und feld[18]=14? alle anderen felder seien mal kleiner 12 dann liefert es doch als ergebnis max=14 pos=18 und nich wie es sein sollte max=36 und pos=14 da es so ja nur den eintrag sucht welcher den größten index hat und gleichzeitig größer als 12 ist oder nicht? bitte korrigiert mich wenn ich falsch liege
lg coR
-
also ich bin eher ein c++ neuling aber ist die funktion so überhaupt korrekt?
Moin,
nein, weil die Variable "max", die in der If-Schleife steht, gar nicht definiert ist
Ist aber sicherlich nur ein Tippfehler und da soll eingentlich "dmax" stehen und in diesem Fall würde der Code wirklich das Maximum suchen, weil sobalt ein Wert z1 größer ist als feld[0] wird dieser in die Variable dmax abgelegt und dann muss im weiteren Verlauf ein anderer Wert z2 größer sein als z1 um in dmax gespeichert zu werden.Beispiel:
#include <iostream> using namespace std; int main() { int feld [10] = {12,8,7,14,13,17,16,18,20,9}; unsigned pos = 0; double dmax = feld[0]; for (unsigned i = 0; i < 10; ++i) { if (feld[i] > dmax) { dmax = feld[i]; pos = i; } } cout<<"Maximum ist an der Stelle: "<< pos<<endl //Ausgabe: 8 <<"Maximum hat den Wert : "<< dmax<<endl; //Ausgabe: 20 system("pause"); return 0; }
-
coR schrieb:
also ich bin eher ein c++ neuling aber ist die funktion so überhaupt korrekt? wenn ich das richtig sehe sucht die schleife doch nur den eintrag der größer ist als feld[0] also den 1. eintrag des feldes.. was ist denn nu wenn zb. feld[0]=12 ist feld[14]=36 und feld[18]=14? alle anderen felder seien mal kleiner 12 dann liefert es doch als ergebnis max=14 pos=18 und nich wie es sein sollte max=36 und pos=14 da es so ja nur den eintrag sucht welcher den größten index hat und gleichzeitig größer als 12 ist oder nicht? bitte korrigiert mich wenn ich falsch liege
du liegst falsch...
es wird anfangs der erste wert des array in max zugewiesen...
wenn nun in der schleife ein wert des array gefunden wird, welcher größer is tals max, bekommt max diesen neuen wert, usw.
-
man kann sich aber auch alles kompliziert machen, templates...
int findMaxPos( double* arr, int start, int end ) { int pos = start; for( int i = start; i < end; ++i ) if( *( arr + i ) > *( arr + pos ) ) pos = i; return pos; }
-
kompliziert schrieb:
man kann sich aber auch alles kompliziert machen, templates...
int findMaxPos( double* arr, int start, int end ) { int pos = start; for( int i = start; i < end; ++i ) if( *( arr + i ) > *( arr + pos ) ) pos = i; return pos; }
Das sieht aber überhaupt nicht cool C++ stylisch aus.
-
void findMaxPos(std::vector<double> *pArray,double &dMax, size_t &iIndex){ std::vector<double>::iterator it= std::max_element (pArray->begin(),pArray->end()); dMax= *it; std::vector<double>::difference_type dInd = distance((pArray->begin() , it ); iIndex=dInd; }
so ungefähr? ungetestet
-
BorisDieKlinge schrieb:
void findMaxPos(std::vector<double> *pArray,double &dMax, size_t &iIndex){ std::vector<double>::iterator it= std::max_element (pArray->begin(),pArray->end()); dMax= *it; std::vector<double>::difference_type dInd = distance((pArray->begin() , it ); iIndex=dInd; }
so ungefähr? ungetestet
warum nicht einfacher mit Referenzen?
void findMaxPos(const std::vector<double> &myArray, double &dMax, size_t &iIndex) { std::vector<double>::iterator it = std::max_element(myArray.begin(), myArray.end()); dMax = *it; std::vector<double>::difference_type dInd = distance((myArray.begin() , it); iIndex = dInd; }
:schland:
-
ja hast recht;) ^^
-
habe meine funktion soweit fertig. Habe nun aber von einem Kollegen gehört, dass Vektoren im Vergleich zu Arrays sehr langsam sein sollen. Leider muss mein Programm bzw die Funktion doch sehr schnell ablaufen(ca 100mal in der Sekunde) so dass ich gerade überlege doch wieder alles umzuschreiben auf arrays. Leider kann ich die Funktion selbst noch nicht testen, daher frage ich hier mal, ob da jemand Erfahrung mit hat!?
-
elsucht schrieb:
habe meine funktion soweit fertig. Habe nun aber von einem Kollegen gehört, dass Vektoren im Vergleich zu Arrays sehr langsam sein sollen. Leider muss mein Programm bzw die Funktion doch sehr schnell ablaufen(ca 100mal in der Sekunde) so dass ich gerade überlege doch wieder alles umzuschreiben auf arrays. Leider kann ich die Funktion selbst noch nicht testen, daher frage ich hier mal, ob da jemand Erfahrung mit hat!?
Ich finde es immer wieder lustig, dass Leute so schnell bereit sind, alles umzuwerfen, nur weil ein Kollege irgendwelche Behauptungen aufstellt. Kann der Kollege diese Behauptungen wenigstens irgendwie untermauern?
Wenn nicht: Teste selbst, und handle wenn Du feststellst, dass Handlungsbedarf besteht, nicht weil irgendein Kollege etwas behauptet hat. Wichtig: Performancemessungen grundsätzlich im Release-Modus durchführen.