max Element in einer Vector
-
Hallo,
ich möcht in zweidimensionale(nx2) Vector max Spaltenelement berechnen und dabei den index alle diese Elementen(es können mehrere sein) merken, die gleichen Wert hat wie Max. Meine Codeausschnitt
#ifndef max #define max(a,b) (((a) > (b)) ? (a) : (b)) #endif ....
vector<double> maxVec_element(vector<vector<double> > vec_element) { std::vector<double> res; std::vector<vector<int> > Indx; // index max. elementen int index; for ( int i = 0; i < 2; i++) // spalten { double currMax = 0.0; for (int j = 0; j < (int)vec_element.size(); j++) { double v = vec_element[j][i]; currMax = max(currMax, v); if (v == currMax) { index = j; Indx.push_back(index); // index hat zu viele elemente } } res.push_back(currMax); } return res; }
was mache ich falsch?
danke im Voraus
ns//Edit: Code tags gefixt
-
ns schrieb:
was mache ich falsch?
Du sagst uns nicht welche Fehlermeldung du bekommst, bzw. was du als Ergebnis erwartest und welches Ergebnis du stattdessen bekommst. (Und wie der zugehörige Inoput aussieht)
-
ich bekomme keine Fehlermeldungen. das Problem ist nur dass ich zu viele Index in Indx vector habe.
if (v == currMax) { index = j; Indx.push_back(index); // index hat zu viele elemente }
-
ns schrieb:
ich bekomme keine Fehlermeldungen. das Problem ist nur dass ich zu viele Index in Indx vector habe.
if (v == currMax) { index = j; Indx.push_back(index); // index hat zu viele elemente }
Nochmal: Was erwartest du? Nur Indizes der größten Elemente des Vektors? Dann ist das falsch, da du auch die Indizes aller Elemente speicherst, die während deiner Suche das bisher größte gefundene Element sind.
-
Also wenn ich das richtig verstanden habe hast du einen vector mit elementen die je 2 spalten haben. Und du möchtest jetzt von jeder spalte am ende größten wert haben. Richtig?
Wenn das so ist dann wäre das hier eine lösung:
struct max_column_elements { max_column_elements( std::vector<double> & res ) : results(res) {} void operator()( std::vector<double> const & row ) { assert( row.size() == results.size() ); for( size_t i = 0; i < row.size(); ++i ){ results[i] = std::max( results[i], row[i] ); } } protected: std::vector<double> & results; }; std::vector<double> maxVec_element(std::vector<std::vector<double> > vec_element) { std::vector<double> res; if( vec_element.size() ){ res.resize( vec_element[0].size() ); std::for_each( vec_element.begin(), vec_element.end(), max_column_elements( res ) ); } return res; }
-
ich danke Dir, werde deine Lösung ausprobieren
-
ns schrieb:
ich danke Dir, werde deine Lösung ausprobieren
Für das Beispiel brauchst du die header:
#include <algorithm> #include <vector> #include <cassert>
-
#ifndef max #define max(a,b) (((a) > (b)) ? (a) : (b)) #endif
Das ist nicht gut. Gar nicht.
- Schreibe Funktionen statt Makros. Damit hast du Typsicherheit und deine Argumente werden nur einfach ausgewertet. Das kann sehr mühsame Fehler und unter Umständen Rechenzeit ersparen.
- Wähle bei Makros NIE so kurze und allgemeingültige Bezeichner. Die Wahrscheinlichkeit, dass du in Namenskonflikte gerätst, ist einfach zu gross. Gerade weil du den Namensraum
std
ausleerst (was du auch vermeiden solltest, besonders in Headerdateien), könntest du leicht Probleme mitstd::max()
bekommen. - Die benötigte Funktionalität gibts schon in der Standardbibliothek: Wie gesagt das Funktionstemplate
std::max()
aus dem Header<algorithm>
.
-
@evilissimo
Mit std::max_element kann man den Code noch verkürzenstruct max_column_element { std::vector<double> &res; max_column_element(std::vector<double> &res) : res(res) { } void operator()(std::vector<double> const &v) { if(not v.empty()) { res.push_back(*std::max_element(v.begin(), v.end())); } } }; std::vector<double> maxVec_element(std::vector<std::vector<double> > const &v) { std::vector<double> res; res.reserve(v.size()); std::for_each(v.begin(), v.end(), max_column_element(res)); return res; }
@ns
std::vector<std::vector<T>>
ist in der Regel nicht ideal, da das ganze viel Verwaltungsoverhead hat. Wenn du eine Matrix haben willst (also in jedem inneren vector eine gleiche Anzahl an Elementen), dann nimm lieber einen vector und bilde x und y entsprechend ab oder nimm gleich etwas wie boost.multi_array.
-
Rüdiger nein. Du hast nicht aufgepasst. Schau dir den op() noch mal genau an
-
oh
ignore my code
-
Wobei ich zugeben muss mein Code hat einen Bug. Wenn in der Liste nur negative werte wären, würde das ganze nicht richtig funktionieren, daher sollte das so sein:
#include <algorithm> #include <vector> #include <cassert> #include <limits> struct max_column_elements { max_column_elements( std::vector<double> & res ) : results(res) {} void operator()( std::vector<double> const & row ) { assert( row.size() == results.size() ); for( size_t i = 0; i < row.size(); ++i ){ results[i] = std::max( results[i], row[i] ); } } protected: std::vector<double> & results; }; std::vector<double> maxVec_element(std::vector<std::vector<double> > vec_element) { std::vector<double> res; if( vec_element.size() ){ res.resize( vec_element[0].size(), std::numeric_limits<double>::min() ); std::for_each( vec_element.begin(), vec_element.end(), max_column_elements( res ) ); } return res; }