我不太了解 std::is_sorted 算法及其默认行为。如果我们期待 cppreference,它默认说 std::is_sorted 使用 < 运营商。而不是那样,我发现使用 <= 会是很自然的。但我的问题是,对于以下数字列表:
1 2 3 3 4 5
它会回来 true, 即使 3 < 3 应该 false。怎么可能?
编辑:它似乎比我想象的更糟糕,因为传递 std::less_equal<int> 在那种情况下将返回false ...当我通过比较器函数时应用的条件是什么?
每25.4 / 5:
序列相对于比较器排序 comp 如果是的话
迭代器 i 指向序列和任何非负整数 n
这样的 i + n 是一个指向元素的有效迭代器
序列, comp(*(i + n), *i) == false。
因此对于
1 2 3 3 4 5
std::less<int>()(*(i + n), *i) 将返回 false 对全部 n,而 std::less_equal 将返回 true 为了案件 3 3。
即使你只有 < 运算符,你可以弄清楚两个数字是否相等,不一定相等。
if !(first < second) and !(second < first)
then first equivalent to second
另外,正如paxdiablo首先提到的解决方案,你可以实现 is_sorted 随着列表上升并不断检查 < 不是真的,如果真的你停下来。
以下是cplusplus.com中该函数的正确行为
template <class ForwardIterator>
bool is_sorted (ForwardIterator first, ForwardIterator last)
{
if (first==last) return true;
ForwardIterator next = first;
while (++next!=last) {
if (*next<*first) // or, if (comp(*next,*first)) for version (2)
return false;
++first;
}
return true;
}
你好像假设它正在检查(对于肯定的情况),如果元素N小于元素N + 1,那么所有元素都是最后一个。这确实不适合 <,虽然你可以使用'技巧'来评估 <= 同 < 和 !:以下两个是等价的:
if (a <= b)
if ((a < b) || (!((b < a) || (a < b)))) // no attempt at simplification.
但是,它更有可能检测到(否定情况)如果元素N小于第一个元素N-1,那么它可以在发现违规时立即停止。那 能够 无所不能 <,像(伪代码):
for i = 1 to len - 1:
if elem[i] < elem[i-1]:
return false
return true