Brauche Hilfe bei code
-
Hallo ich habe eine Matrix die in einem std::vector lnear abgespeichert ist.
Nun möchte ich alle Zeilen der matrix löschen in denen eine Null vorkommt.
Also beispiel:
die matrix:
1 0 4
0 0 0
-2 1 2
0 3 2
0 0 0das array sieht damit so aus: std::vector = 1 0 4 0 0 0 -2 1 2 0 3 2 0 0 0
die ergebnismatrix sieht dann so aus:
1 0 4
-2 1 2
0 3 2es wurden also zeile 1 und 4 gelöscht.
der vector sieht so aus: std::vector = 1 0 4 -2 1 2 0 3 2Irgendwie stelle ich mich da dumm an.
Mein code der das schonmal schafft sieht so aus wobei ich glaub das er sehr ineffizient ist. Für Vorschläge bin ich sehr dankbar!!!
int offset = 0; bool found = 0; for(int row = 0; row < nbr_Matrix_rows; row++) { for(int col = 0; col < y_dim; col++) { offset = col + row * y_dim; if (tmp_Matrix[offset] != 0) { erg_Matrix.push_back(tmp_Matrix[offset]); continue; } for(int r = 0; r < nbr_Matrix_rows; r++) if(tmp_Matrix[col + r * y_dim] != 0.0) found = 1; if(found) erg_Matrix.push_back(tmp_Matrix[offset]); found = 0; } }
-
Also wenn du nur die Zeilen rauslöschen möchtest in denen 0,0,0 vorkommt dann würde ich das so machen. Mag sein das es einen effizienteren Weg gibt aber der auf den komme ich just in diesem Moment nicht

for(int i = 0; i < nbr_Matrix_rows; ++i) { int idx = i * y_dim; bool found = true; for(int j = 0; found && j < y_dim; ++j) found = !vec[idx+j]; if(found) { vector<int>::iterator it = vec.begin() + idx; vec.erase(it,it+y_dim); // löscht die zeile --rows; // anpassen der zeilen anzahl --i; // anpassen der aktuellen Zeile } }Wie du siehst ist er nicht viel anders als dein code

BR
Vinzenz
-
Hi!
for ( int i = 0; i < rows; ++i ) { std::vector< int >::iterator it = matrix.begin()+i*dim; int num = count_if( it, it+dim, std::bind2nd( std::equal_to< int >(), 0 ) ); if ( num == 3 ) { matrix.erase( it, it+dim ); --rows; --i; } }
-
for ( std::vector< int >::iterator it = matrix.begin(); it != matrix.end(); ) { if ( find_if( it, it + dim, std::bind2nd( std::not_equal_to< int >(), 0 ) ) == it + dim ) it = matrix.erase( it, it + dim ); else it += dim; }
-
camper schrieb:
for ( std::vector< int >::iterator it = matrix.begin(); it != matrix.end(); ) { if ( find_if( it, it + dim, std::bind2nd( std::not_equal_to< int >(), 0 ) ) == it + dim ) it = matrix.erase( it, it + dim ); else it += dim; }

-
evilissimo schrieb:
camper schrieb:
for ( std::vector< int >::iterator it = matrix.begin(); it != matrix.end(); ) { if ( find_if( it, it + dim, std::bind2nd( std::not_equal_to< int >(), 0 ) ) == it + dim ) it = matrix.erase( it, it + dim ); else it += dim; }

hat allerdings O(n^2) komplexität. effizienter dürfte
std::vector< int >::iterator t = matrix.begin(); for ( std::vector< int >::iterator it = t; it != matrix.end(); it += dim ) { if ( find_if( it, it + dim, std::bind2nd( std::not_equal_to< int >(), 0 ) ) != it + dim ) { copy( it, it + dim, t ); t += dim; } } matrix.erase( t, matrix.end() );sein.
-

Grosses Dankeschön an alle die hier gepostet haben! Ihr seid immer eine grosse klasse Hilfe wenn man vor Lauter Bäumen den Wald kaum mehr sieht
Danke
-
Hallo, ich bins nochmal,
habt ihr das auch getestet? wenn ich die ausgangsmatrix nach der schleife ausgebe scheint sich rein gar nichts geändert zu haben.
Ich habe es mit jeder Methode versucht die ihr gepostet habt. AN meiner ausgabe liegt es nicht das habe ich bereits überprüft. Ich lege die Matrix auch nur so an:std::vector<double> matrix;
und fülle sie dann mit push_back. Mehr auch nicht.
Es kann doch nicht daran liegen dass ich double als type des vectors hernehme...natürlich habe ich die int durch double im code von euch ersetzt.
Er läuft zwar in die Schleifen aber das erase scheint nicht zu klappen...naja ich mach mich mal weiter nach der Fehlersuche.hier mal mein testcode
std::vector<int> matrix; matrix.push_back(0); matrix.push_back(4); matrix.push_back(2); matrix.push_back(0); matrix.push_back(3); matrix.push_back(2); matrix.push_back(0); matrix.push_back(2); matrix.push_back(1); int dim = 3; std::vector< int >::iterator t = matrix.begin(); for ( std::vector< int >::iterator it = t; it != matrix.end(); it += dim ) { if ( find_if( it, it + dim, std::bind2nd( std::not_equal_to< int >(), 0 ) ) != it + dim ) { copy( it, it + dim, t ); t += dim; } } matrix.erase( t, matrix.end() ); std::cout << "Test-------------: " << std::endl; std::vector<int>::iterator it2; for(it2 = matrix.begin(); it2 != matrix.end(); it2++) std::cout << *it2 << std::endl
-
Zum Testen wäre es wohl gut, wenn wirklich "Nullzeilen" in der Matrix drin wären.
-

Das sind sie:
000
432
221ich speichere spaltenweise
ausserdem ändert das nichts an der tatsache.
Folgender code ist da ebenfalls für mich nicht ganz verständlich. Anscheinend hab ichs erase nicht kapiert:
std::vector<char> alphaVector; for( int i=0; i < 10; i++ ) { alphaVector.push_back( i + 65 ); } int size = alphaVector.size(); std::vector<char>::iterator startIterator; std::vector<char>::iterator tempIterator; std::vector<char>::iterator ittest; for( int i=0; i < size-3; i++ ) { startIterator = alphaVector.begin(); alphaVector.erase( startIterator ); // Display the vector //for( tempIterator = alphaVector.begin(); tempIterator != alphaVector.end(); tempIterator++ ) { // std::cout << *tempIterator; //} //std::cout << std::endl; } for (ittest = alphaVector.begin(); ittest != alphaVector.end(); ittest++ ) std::cout << *ittest << std::endl;
-
Mati schrieb:
ich speichere spaltenweise
Tja, in deiner ursprünglichen Frage war es ganz offensichtlich zeilenweise. Da sollte es dich nicht wundern, dass das nicht klappt.
-
Sorry mein Fehler. Habe im Anfangsposting gesagt ich speichere zeilenweise
wollte aber posten auf spaltenweise wie ichs eigentlich will. *grmpfmeine ersten versuche den code zu ändern sind ganz schön schwer für nen Anfänger...
das dumme ich ich muss zeilenweise durchlaufen habe aber eine spaltenweise speicherung.also:
0 0 0
3 2 1
0 0 0ist so gespeichert: 0 3 0 0 2 0 0 1 0
und soll so ergebnis sein:
3 2 1
und so als ergebnis abgespeichert sein: 3 2 1

ich merke gerade dass das die sache aufwändig macht, da ich es aber leider so brauche wäre es nett wenn wir die sache noch mal aufrollen könnten: Ich glaube zusätzlich dass es nicht in einer Komplexität < O^2 zu lösen ist.
Ein find_if ist jetzt auch nimmer möglich weil ich ja sprünge machen muss.Danke für erneute Hilfestellungen...
-
bin immer noch dran uns schaffe es nicht das Problem auf eine andere Art zu lösen....bin immer noch dankbar für jede Hilfe

-
mir fällt erst einmal so etwas ein:
#include <iostream> #include <ostream> #include <vector> #include <algorithm> #include <iterator> #include <functional> struct IsMasked { IsMasked(const std::vector< double >& matrix, const std::vector< bool >& mask) : matrix_( &matrix ), mask_( mask ) {} bool operator()(const double& f) const { return mask_[ ( &f - &*matrix_->begin() ) % mask_.size() ]; } std::vector< bool > mask_; const std::vector< double >* matrix_; }; void erase_null(std::vector< double >& matrix, int x_dim, int& y_dim) { std::vector< bool > mask( y_dim ); for ( int y = 0; y < y_dim; ++y ) { mask[ y ] = true; for ( int x = 0; x < x_dim; ++x ) { if ( matrix[ x * x_dim + y ] != 0 ) { mask[ y ] = false; break; } } } matrix.erase( std::remove_if( matrix.begin(), matrix.end(), IsMasked( matrix, mask ) ), matrix.end() ); y_dim = matrix.size() / x_dim; } void main() { std::vector<double> matrix; matrix.push_back(0); matrix.push_back(4); matrix.push_back(2); matrix.push_back(0); matrix.push_back(3); matrix.push_back(2); matrix.push_back(0); matrix.push_back(2); matrix.push_back(1); int x_dim = 3, y_dim = 3; for ( int y = 0; y < y_dim; ++y ) { for ( int x = 0; x < x_dim; ++x ) std::cout << matrix[ x * y_dim + y ] << '\t'; std::cout << std::endl; } std::cout << "*******" << std::endl; erase_null( matrix, x_dim, y_dim ); for ( int y = 0; y < y_dim; ++y ) { for ( int x = 0; x < x_dim; ++x ) std::cout << matrix[ x * y_dim + y ] << '\t'; std::cout << std::endl; } }besonders elegant ist das nicht, aber dafür auch nicht schwer zu verstehen. wollte man hier auch find_if & co einsetzen, müsste man sich einen geeigneten iterator basteln, das ist für diesen einen einsatz allerdings ein wenig overkill.
-
vielen dank. Ich brauch schon über ne halbe stunde um überhaupt den code zu verstehen

Ajajaj. Ich darf noch viiiieeel lernen.
-
Puh das struct hats in sich
Wenn jemand schnell vorbeikommt und lust hat mir zu erklären
was genau da passiert bin ich dankbar.
Sehe ich das richtig dass über den aufuf des operators IsMasked() mit den klammern automatisch der ausdruck bool operator() ...ausgewertet wird also der return type bool ist?
Woher kommt aber das const double&f ?
Und warum wird bei matrix.erase( std::remove_if( matrix.begin(), matrix.end(), IsMasked( matrix, mask ) ), matrix.end() );
zweimal ein remove angestellt?
-
trotz seines namens entfernt remove keine elemente aus dem vector, sondern sortiert nur um. das ergebnis ist eine sequenz, die nur die elemente enthält, für die das übergebene prädikat nicht wahr ist. zurückgegeben wird dabei nur das ende der sequenz, denn der anfang stimmt mit dem input überein. ohne standardalgorithmen könnte das so aussehen:
int t = 0; for ( int s = 0; s < matrix.size(); ++s ) if ( !mask[ s % y_dim ] ) matrix[ t++ ] = matrix[ s ]; matrix.resize( t );
-
danke camper,
das habe ich nun soweit begriffen. Aber könntest du/ihr mir noch kurz das struct erklären. Ich blick vor allem beim bool operator net ganz durch

struct IsMasked { IsMasked(const std::vector< double >& matrix, const std::vector< bool >& mask) : matrix_( &matrix ), mask_( mask ) {} bool operator()(const double& f) const { return mask_[ ( &f - &*matrix_->begin() ) % mask_.size() ]; } std::vector< bool > mask_; const std::vector< double >* matrix_; };
-
mask_[ ( &f - &*matrix_->begin() ) % mask_.size() ]entspricht dem ausdruck
mask[ s % y_dim ]in der version mit schleife. die schwierigkeit ist, an den index s heranzukommen. hierbei nutze ich aus, dass vector seine daten kontinuierlich speichert, und nutze pointerarithmetik.
ich hätte auchmask_[ ( &f - &(*matrix_)[0] ) % mask_.size() ]schreiben können, aber ich bin kein großer fan von vermeidbaren klammern

-
danke

das f ist mein Problemfall...
woher stammt das f ?
ich verstehe nicht ganz wo der operator angewandt wird?