我在is_sorted上遇到了一个古老的问题:std::is_sorted and strictly less comparison?
在遇到用对比较器进行单调性检查未能通过测试的用例时,。我以为如下所示的lambda符合要求:(仅当lhs和rhs的两个元素都已排序时)它会返回true
bool
check_pair_sorted(std::vector<std::pair<int, int>>& vec)
{
return std::is_sorted(vec.begin(), vec.end(),[](auto& lhs, auto& rhs){
return (lhs.first < rhs.first) && (lhs.second < rhs.second);
});
}
但是,如果我像这样分割支票,那么真正的预期功能是可能的
bool check_separate_sorted(std::vector<std::pair<int, int>>& vec)
{
return std::is_sorted(vec.begin(), vec.end(),[](auto& lhs, auto& rhs){
return (lhs.first < rhs.first) ; })
&& std::is_sorted(vec.begin(), vec.end(),[](auto& lhs, auto& rhs){
return (lhs.second < rhs.second) ; });
}
看看上面的问题的答案,即建议较早返回false可能是首选的实现方式,是否也应同样提出要求?
comp-比较函数对象(即满足Compare要求的对象),如果第一个参数小于或等于(即,则返回 false ) (不是之前)。
我在这里订购时可能会遗漏一些东西,但目前似乎无法将其包裹住。
答案 0 :(得分:2)
您的check_pair_sorted
与check_separate_sorted
所做的事情有所不同,我想这就是混乱的根源。
这取决于std::is_sorted
的定义方式。对于每两个元素a[i]
和a[j]
,其中i
<j
:
a[j] < a[i]
永远不是真的a[i] < a[j]
始终为真(自然,聪明的算法可以避免进行所有O(n ^ 2)比较)
上面的两颗子弹不一样!
对于简单数字,如在另一个SO问题中一样,序列1 2 3 3 4 5
满足第一个点,但不满足后者。
您的情况类似的情况。考虑两对的序列:{ {1,2}, {2,1} }
。序列的元素不同,但是第一个lambda比较器无法比较它们-双向返回false
。因此,出于该算法的目的,即使这两个元素不是严格相等的,也将它们视为等效。
因此,is_sorted
内的check_pair_sorted
序列{ {1,2}, {2,1} }
将返回true
,因为它检查的是第一个项目符号点,而不是第二。
请注意,相同的等效问题可能会影响其他STL结构和算法。例如,如果您有一个std::set
,则无法使用第一个Lambda作为比较器同时包含{1,2}
和{2,1}
元素。
答案 1 :(得分:1)
std::is_sorted在比较函数-运算符<()或某些功能对象-在TS的示例中为lambda明确定义。
但是,如果以这种方式构造比较函数,则两个元素之间没有明确的关联-即 a 和 b 都是 true -无法完全定义任何排序或排序操作的结果。
这是造成混乱的真正原因。
答案 2 :(得分:0)
对于词汇排序,您需要:
return (lhs.first < rhs.first) || ((lhs.first == rhs.first) && lhs.second < rhs.second));