Brauche Hilfe bei code



  • 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;
    }
    

    👍 🕶


  • Mod

    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
    221

    ich 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. *grmpf

    meine 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 0

    ist 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 😉


  • Mod

    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?


  • Mod

    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_; 
     };
    

  • Mod

    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 auch

    mask_[ ( &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?


Anmelden zum Antworten