Results 1 to 9 of 9

Thread: vector & remove_if

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1
    Join Date
    Jan 2006
    Posts
    976
    Thanks
    53
    Qt products
    Qt3
    Platforms
    Windows

    Default vector & remove_if

    Hello,
    this below doens't work but it gives the idea (hope) of my problem:
    Qt Code:
    1. class Feature {
    2. public:
    3.  
    4. bool isNotValid(int i) {
    5. return this->_indexMissedMask[i];
    6. }
    7. void compute() {
    8. vector<double>::iterator iter = remove_if(validValue.begin(),
    9. validValue.end(), &Feature::isNotValid );
    10.  
    11. }
    To copy to clipboard, switch view to plain text mode 
    _indexMissedMask is a vector of bool like this: false, false, true, false........
    I have to remove from validValue all elements at the position with _indexMissedMask is "true".
    Any hints, please?
    Regards

  2. #2
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,368
    Thanks
    3
    Thanked 5,018 Times in 4,794 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: vector & remove_if

    Qt Code:
    1. for(int i = validValue.size()-1;i>=0;i--)
    2. if(_indexMissedMask[i])
    3. validValue.removeAt(i); // or equivalent
    To copy to clipboard, switch view to plain text mode 

  3. The following user says thank you to wysota for this useful post:

    mickey (10th August 2008)

  4. #3
    Join Date
    Jan 2006
    Posts
    976
    Thanks
    53
    Qt products
    Qt3
    Platforms
    Windows

    Default Re: vector & remove_if

    Quote Originally Posted by wysota View Post
    Qt Code:
    1. for(int i = validValue.size()-1;i>=0;i--)
    2. if(_indexMissedMask[i])
    3. validValue.removeAt(i); // or equivalent
    To copy to clipboard, switch view to plain text mode 
    How always you've found the simplest solution (that always was there)....
    But wanting use that way above, just only to learn to use algorithm generics....how could I do?
    Furthermore: isn't "remove_if" above faster than your suggestion?
    thanks,
    Regards

  5. #4
    Join Date
    Dec 2006
    Posts
    849
    Thanks
    6
    Thanked 163 Times in 151 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: vector & remove_if

    you have to erase the rest... remove_if does not erase the elements. it reorders the vector and returns an iterator pointing to the 'new end'.

    See http://www.sgi.com/tech/stl/remove_if.html

  6. #5
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,368
    Thanks
    3
    Thanked 5,018 Times in 4,794 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: vector & remove_if

    Quote Originally Posted by mickey View Post
    But wanting use that way above, just only to learn to use algorithm generics....how could I do?
    You have to start with the last element and not the first one, that's for sure. Otherwise probably your iterators/indexes on both containers will go out of sync.

    Furthermore: isn't "remove_if" above faster than your suggestion?
    No, you can't get better than O(n) here - you have to check each element (so it's actually omega(n) and theta(n)).

  7. #6
    Join Date
    Jan 2006
    Posts
    976
    Thanks
    53
    Qt products
    Qt3
    Platforms
    Windows

    Default Re: vector & remove_if

    Quote Originally Posted by wysota View Post
    Qt Code:
    1. for(int i = validValue.size()-1;i>=0;i--)
    2. if(_indexMissedMask[i])
    3. validValue.removeAt(i); // or equivalent
    To copy to clipboard, switch view to plain text mode 
    hello,
    I write this and seems work but I don't know why. In fact, I encountered some problem from the fact that, when I call erase(), the size of vector change and increment the iterator can cause crash at runtime:
    Qt Code:
    1. vector<double>::iterator ivalid = validValue.end() - 1;
    2. vector<bool>::iterator imask = _indexMissedMask.end() - 1;
    3. for ( ; imask != _indexMissedMask.begin(); --imask, /*--ivalid*/) { //here "--ivalid crash program"
    4. if ( *imask )
    5. validValue.erase(ivalid--);
    6. }
    To copy to clipboard, switch view to plain text mode 
    Could you tell me why there crash "--ivalid", please?
    Regards

  8. #7
    Join Date
    Dec 2006
    Posts
    849
    Thanks
    6
    Thanked 163 Times in 151 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: vector & remove_if

    If you erase the element at ivalid you decrement the iterator twice.
    once in the loop's body, and once in the for-statement.

    Coding (even such trivial) stuff again just introduces further possibilities for errors. Try to use the available algorithms like remove_if, erase etc.

    HTH

  9. #8
    Join Date
    Jan 2006
    Posts
    976
    Thanks
    53
    Qt products
    Qt3
    Platforms
    Windows

    Default Re: vector & remove_if

    sorry,
    what I meant was:
    This seems work:
    Qt Code:
    1. vector<double>::iterator ivalid = validValue.end() - 1;
    2. vector<bool>::iterator imask = _indexMissedMask.end() - 1;
    3. for ( ; imask != _indexMissedMask.begin(); --imask) {
    4. if ( *imask )
    5. validValue.erase(ivalid--);
    6. }
    To copy to clipboard, switch view to plain text mode 
    This crashes:
    Qt Code:
    1. vector<double>::iterator ivalid = validValue.end() - 1;
    2. vector<bool>::iterator imask = _indexMissedMask.end() - 1;
    3. for ( ; imask != _indexMissedMask.begin(); --imask, --ivalid) {
    4. if ( *imask )
    5. validValue.erase(ivalid);
    6. }
    To copy to clipboard, switch view to plain text mode 
    Why, please?
    Regards

  10. #9
    Join Date
    Dec 2006
    Posts
    849
    Thanks
    6
    Thanked 163 Times in 151 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: vector & remove_if

    The code above is wrong (twice decrementing of iterator).
    The code below is wrong, too: after erase() the iterator ivalid is no longer valid.
    You would have to do something like

    Qt Code:
    1. vector<double>::iterator ivalid = validValue.end() - 1;
    2. vector<bool>::iterator imask = _indexMissedMask.end() - 1;
    3. for ( ; imask != _indexMissedMask.begin(); --imask)
    4. {
    5. vector<double>::iterator tmp = ivalid;
    6. --tmp;
    7. if ( *imask )
    8. validValue.erase(ivalid); // invalidates ivalid; would return iterator pointing behind it
    9. ivalid=tmp;
    10. }
    To copy to clipboard, switch view to plain text mode 
    (untested, of course)

    This is why you should not reinvent the wheel yourself. Use the algorithms.

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Qt is a trademark of The Qt Company.