c++和python中一个自定义cmp的坑

应该是一个坑,关于python和c++中的自定义cmp函数这一块的。

首先发现这个问题是在力扣每日一题:1333. 餐厅过滤器

然后前后两次用c++和python分别写了一次,c++速通了,然后被python的cmp函数折磨的云里雾里。

先给c++的代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
bool cmp(vector<int> &a, vector<int> &b) {
if (a[1] > b[1]) return true;
else if (a[1] == b[1]) {
if (a[0] > b[0]) return true;
else return false;
} else {
return false;
}
}

class Solution {
public:
vector<int> filterRestaurants(vector<vector<int>>& restaurants, int veganFriendly, int maxPrice, int maxDistance) {
vector<vector<int>> ans;
for (int i = 0; i < restaurants.size(); i++) {
vector<int> cur = restaurants[i];
if (cur[2] >= veganFriendly && cur[3] <= maxPrice && cur[4] <= maxDistance) {
ans.push_back(cur);
cout << cur[0];
}
}
sort(ans.begin(), ans.end(), cmp);
vector<int> res;
for (auto i : ans) {
res.push_back(i[0]);
}
return res;
}
};

然后看python

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
def cmp1(a, b):
if a[1] - b[1] != 0:
return a[1] - b[1]
else:
return a[0] - b[0]


class Solution:
def filterRestaurants(self, restaurants, veganFriendly, maxPrice, maxDistance):
ans = []
for cur in restaurants:
if cur[2] >= veganFriendly and cur[3] <= maxPrice and cur[4] <= maxDistance:
ans.append(cur)
ls = sorted(ans, key=cmp_to_key(cmp1), reverse = True)
res = []
for i in ls:
res.append(i[0])
return res

首先提一点,python里的这个cmp只能返回整数,大于整数等于零小于负数这样子,返回bool是不认的。
相反,c++返回的就是bool。

重点在于,虽然两个cmp函数的逻辑是一样的,对相同输入返回的比较结果也是一样的,但是在python的sorted中,reverse字段设置为了True。

这也是二者的差异所在,在默认的情况下,c++的cmp函数返回的更像是是一个权重结果,权重更高的元素会放在前面;但是python的cmp返回的是比较结果,而其中更大的数会放在后面(默认升序)。

当然这道题python的排序函数也可以写成这样,相对更省事:

1
ls = sorted(ans, key=lambda x:(x[1],x[0]), reverse = True)