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

我的算法是

  • 开始对序列
  • 进行迭代
  • 如果present元素不满足谓词,则将其替换为最后一个
  • 再次检查相同位置的新元素是否满足要求
  • 如果不将其替换为(last-1),则使用
  • 重复直到达到我们已替换
  • 的元素之一

    我的密码
    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;
    }
    

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

    我找不到和了解。即,我可以在试图取消引用容器外部元素的地方看到它,但是在我的程序中看不到它。谁能帮助我解决编码错误或改善算法逻辑?

    最佳答案

    如果输入范围为非空并且其中的任何元素都不满足谓词,则您的代码将停留在goto循环中,而不会再次到达while。最终,--end将在end之前接受first

    如果这是一项学习练习,建议您摆脱goto;您不想学习不良做法,虽然goto可能有罕见的合法用途,但替换循环并不是其中之一。同样,可以将tmp替换为std::swap

    如果这不是学习练习,只需使用 std::partition 即可完成您想要的操作。

    10-06 05:07
    查看更多