简体   繁体   English

使用谓词通过谓词重新排列

[英]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. 在具有给定签名的函数中,我想以这种方式重新排列序列的元素[first,last),将所有满足谓词的元素放在不满足条件的元素之前,并将迭代器返回给不满足给定条件的第一个元素谓语。

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 如果未替换为(last-1),则请继续
  • 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. 如果输入范围非空,并在其中没有元素满足谓词,你的代码将被卡在goto循环,不能达到while一次。 Eventually, --end will take end before first . 最终,-- --end将在first之前end

If this is a learning exercise, I suggest you get rid of goto ; 如果这是一项学习练习,建议您摆脱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. 您不希望学习不良做法,尽管goto可能有罕见的合法用途,但替换循环并不是其中之一。 Also, the dance with tmp can be replaced with std::swap . 同样,可以将tmp跳舞替换为std::swap

If this is not a learning exercise, just use std::partition which does exactly what you want. 如果这不是一个学习练习,只需使用std::partition完成您想要的操作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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