在adjacent_find中使用greater_equal在排序序列中查找等效元素

Use greater_equal in adjacent_find to find equivalent elements in sorted sequence

本文关键字:元素 查找 greater find adjacent equal 排序      更新时间:2023-10-16

算法std::adjacent_find中使用std::greater_equal在排序范围内查找等效(与相等相反(元素是UB吗?

如果未严格指定算法实现内部std::greater_equal<>{}(*prev, *next)一个下一个元素的顺序,则答案可能是"否"。

std::container<int> c{1, 2, 3, 3, 4, 5};
assert(std::is_sorted(std::cbegin(c), std::cend(c));
assert(std::adjacent_find(std::cbegin(c), std::cend(c), std::greater_equal<int>{}) != std::cend(c));

std::adjacent_find搜索谓词返回true的两个连续元素。C++标准将行为记录为查找:

  • *i == *(i + 1)没有参数pred的重载
  • pred(*i, *(i + 1)) != false参数重
  • pred

第二个项目符号指定元素传递给谓词的顺序。

此示例实现(从 cppreference.com 复制(应该更清楚地说明这一点。

template<class ForwardIt, class BinaryPredicate>
ForwardIt adjacent_find(ForwardIt first, ForwardIt last, BinaryPredicate p)
{
    if (first == last) {
        return last;
    }
    ForwardIt next = first;
    ++next;
    for (; next != last; ++next, ++first) {
        if (p(*first, *next)) { // <- predicate called here
            return first;
        }
    }
    return last;
}
在 std::

adjacent_find 算法中使用 std::less 来查找是 UB 吗 排序范围内的等效(与相等相反(元素?

它从来都不是未定义的行为,传递给std::adjacent_find谓词的唯一限制是适当的类型,而不是修改其参数。

您正在查看此模板:

template< class ForwardIt, class BinaryPredicate>
ForwardIt adjacent_find( ForwardIt first, ForwardIt last, BinaryPredicate p );

这里p

p - 二进制谓词,如果元素应被视为相等,则返回 true。

只要满足算法的要求,这里就没有UB。如果对于您的问题,您必须将less视为equal那么它是完全有效的。

你没有 UB,但你想要的不是std::less1 < 2,它会将迭代器返回到 1

你需要:

std::vector<int> c{1, 2, 3, 3, 4, 5};
assert(std::is_sorted(std::cbegin(c), std::cend(c));
auto it = std::adjacent_find(std::cbegin(c), std::cend(c),
                             [](auto lhs, auto rhs){
                                 // For unsorted container, you would need
                                 // return !(lhs < rhs) && !(rhs < lhs);
                                 // but as container is sorted,
                                 // we already have (lhs < rhs) || !(rhs < lhs)
                                 return !(lhs < rhs);
                             });
// *it == 3; *(it+1) == 3;