C++ 为什么这个简单的自定义元组比较器即使在严格弱排序的情况下也会崩溃?
这个用于类型C++ 为什么这个简单的自定义元组比较器即使在严格弱排序的情况下也会崩溃?,c++,sorting,std,comparator,custom-compare,C++,Sorting,Std,Comparator,Custom Compare,这个用于类型元组的简单自定义比较器在下面的示例测试中崩溃。我使用cmp比较器中的cout语句检查了对cmp的每次调用都会得到一个返回值,因此元组t1和t2中的值不是垃圾 知道为什么会这样吗?这个非常简单的定制比较器有什么问题吗 class Solution { public: vector<int> assignBikes(vector<vector<int>>& ws, vector<vector<int>>&
元组的简单自定义比较器在下面的示例测试中崩溃。我使用cmp
比较器中的cout
语句检查了对cmp
的每次调用都会得到一个返回值,因此元组t1和t2中的值不是垃圾
知道为什么会这样吗?这个非常简单的定制比较器有什么问题吗
class Solution {
public:
vector<int> assignBikes(vector<vector<int>>& ws, vector<vector<int>>& bs) {
int n = ws.size(), m = bs.size();
vector<tuple<int, int, int>> dist;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
int d = abs(ws[i][0]-bs[j][0]) + abs(ws[i][1]-bs[j][1]);
dist.push_back(make_tuple(d, i, j));
}
}
sort(dist.begin(), dist.end(), cmp());
}
struct cmp {
bool operator() (tuple<int, int, int>& t1, tuple<int, int, int>& t2) {
int d1 = get<0>(t1), d2 = get<0>(t2), w1 = get<1>(t1), w2 = get<1>(t2), b1 = get<2>(t1), b2 = get<2>(t2);
cout << d1 << " " << w1 << " " << b1 << " " << d2 << " " << w2 << " " << b2 ;
bool ret = false;
if (d1 < d2) ret = true;
else if (w1 < w2) ret = true;
else if (b1 < b2) ret = true;
cout << " " << ret << " " << endl;
return ret;
}
};
};
int main() {
Solution s;
vector<vector<int>> ws = {{0,0},{1,0},{2,0},{3,0},{6,0}};
vector<vector<int>> bs = {{0,999},{1,999},{2,999},{3,0},{6,0}};
s.assignBikes(ws, bs);
}
类解决方案{
公众:
向量赋值(向量与ws、向量与bs){
int n=ws.size(),m=bs.size();
向量距离;
对于(int i=0;i cout您的cmp
操作符()
没有严格的弱顺序。例如,在比较w1
等之前,您需要检查d1==d2
。这违反了调用未定义行为的std::sort
的要求。这可能会导致崩溃
正确的简单实现是:
bool operator() (std::tuple<int, int, int> const & t1, std::tuple<int, int, int> const & t2) {
int d1 = std::get<0>(t1), d2 = std::get<0>(t2), w1 = std::get<1>(t1), w2 = std::get<1>(t2), b1 = std::get<2>(t1), b2 = std::get<2>(t2);
return std::tie(d1, w1, b1) < std::tie(d2, w2, b2);
}
您的cmp
运算符()
没有严格的弱顺序。例如,在比较w1
等之前,您需要检查d1==d2
。这违反了调用未定义行为的std::sort
的要求。这可能会导致崩溃
正确的简单实现是:
bool operator() (std::tuple<int, int, int> const & t1, std::tuple<int, int, int> const & t2) {
int d1 = std::get<0>(t1), d2 = std::get<0>(t2), w1 = std::get<1>(t1), w2 = std::get<1>(t2), b1 = std::get<2>(t1), b2 = std::get<2>(t2);
return std::tie(d1, w1, b1) < std::tie(d2, w2, b2);
}
您的自定义比较器没有严格的弱顺序。例如,如果t1={1,2,0},t2={2,1,0},那么cmp(t1,t2)和cmp(t2,t1)都是true,这违反了严格的弱顺序
既然已经有了元组,为什么不
bool operator() (const tuple<int, int, int>& t1, const tuple<int, int, int>& t2) {
return t1 < t2;
}
bool操作符()(常量元组&t1,常量元组&t2){
返回t1
或者更简单的是,完全忽略比较器,因为默认的std::sort
已经满足了您(大概)的需要。您的自定义比较器没有严格的弱顺序。例如,如果t1={1,2,0}和t2={2,1,0},那么cmp(t1,t2)和cmp(t2,t1)都是true,这违反了严格的弱顺序
既然已经有了元组,为什么不
bool operator() (const tuple<int, int, int>& t1, const tuple<int, int, int>& t2) {
return t1 < t2;
}
bool操作符()(常量元组&t1,常量元组&t2){
返回t1
或者更简单的方法是完全忽略比较器,因为std::sort
的默认值已经满足了您(大概)的需要。您的操作符
实际上没有正确地实现严格的弱排序,因此对std::sort()
的调用具有未定义的行为
你在评论中说:
我需要对它们进行排序,以便首先选择较低的d
,如果d
相同,则首先选择较低的w
,如果w
相同,则首先选择较低的b
但是您的比较器缺少对这些元组值的相等性检查
由于d
是第一个元组元素,w
是第二个元组元素,b
是第三个元组元素,因此最简单的解决方案是根本不手动比较元组元素,只需按原样比较元组本身。默认情况下,将对严格弱排序执行正确的比较,正如您所做的那样nted:
通过操作符对lhs
和rhs
进行字典式比较operator您的操作符实际上没有正确地实现严格的弱排序,因此对std::sort()
的调用具有未定义的行为
你在评论中说:
我需要对它们进行排序,以便首先选择较低的d
,如果d
相同,则首先选择较低的w
,如果w
相同,则首先选择较低的b
但是您的比较器缺少对这些元组值的相等性检查
由于d
是第一个元组元素,w
是第二个元组元素,b
是第三个元组元素,因此最简单的解决方案是根本不手动比较元组元素,只需按原样比较元组本身。默认情况下,将对严格弱排序执行正确的比较,正如您所做的那样nted:
通过运算符按字典顺序比较lhs
和rhs
您的自定义比较器没有严格的弱排序。您的assignBikes
具有未定义的行为有两个原因:一个原因是关于排序错误的答案。发生崩溃的另一个原因是您没有返回任何内容从Solution::assignBikes
返回std::vector
。编译器应该警告您没有从该函数返回值。您的自定义比较器没有严格的弱顺序。您的assignBikes
具有未定义的行为有两个原因:一个是由答案给出的关于排序错误。可能发生崩溃的另一个原因是,当您应该返回std::vector
时,您没有从Solution::assignBikes
返回任何内容。您的编译器应该警告您没有从该函数返回值。这是一个好的解决方案;可能不是最容易阅读的,在它当前的形式下,swithwings True,将它清理了一点。哦,好得多。比我建议的改进更好。萝拉,没有意识到它不是严格弱有序的。有没有一种标准化的方法来确保对于复杂类型,一个人写一个严格弱有序的比较器