简体   繁体   中英

Rearrange by predicate using iterators

In a function with given signature I want to rearrange elements of sequence [first, last) in a such way, that all elements satisfying predicate are placed before ones that don't and return an iterator to a first element that doesn't satisfy given predicate.

My algorithm is

  • Start iterating on sequence
  • If present element doesn't satisfy predicate replace it with the last one
  • Check again if a new element on the same position satisfy it
  • If not replace it with (last-1), if yes just proceed further
  • Repeat until we reach one of the elements that we have already replaced

My code

template<class Iterator, class Predicate>
Iterator Rearrange(Iterator first, Iterator last, Predicate pred) {
  auto res = first;
  if (first == last) {
    ;
  }
  else {
    auto run = first;
    auto end = last;
    auto tmp = *first;
    while (run != end) {
      if (pred(*run) == false) {
      again: tmp = *(--end);
    *end = *run;
    *run = tmp;
    if (pred(*run) == false) {
      goto again;
    }
      }
      ++run;
    }
  }
  return res;
}

it gives me

terminate called after throwing an instance of 'std::range_error'
  what():  dereferencing end of sequence
Aborted

which I can't find and understand. Namely, I can read that somewhere I'm trying to dereference element outside of container, but can't see it in my program. Can anyone help me fix a coding error or improve logic of my algorithm?

If the input range is non-empty and no element in it satisfies the predicate, your code will be stuck in the goto loop and not reach the while again. Eventually, --end will take end before first .

If this is a learning exercise, I suggest you get rid of goto ; you don't want to be learning bad practices and while goto can have rare legitimate uses, replacing loops is not one of them. Also, the dance with tmp can be replaced with std::swap .

If this is not a learning exercise, just use std::partition which does exactly what you want.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM