C++ std::使用自定义比较器设置操作
我有个问题。当我使用带有自定义比较器的std::set时,其他操作(如擦除或计数)无法正常工作。 例如:C++ std::使用自定义比较器设置操作,c++,c++11,std,stdset,C++,C++11,Std,Stdset,我有个问题。当我使用带有自定义比较器的std::set时,其他操作(如擦除或计数)无法正常工作。 例如: int sz(int const & n) { return __builtin_popcount(n); } struct comp { bool operator()(int const & a, int const & b) const { return sz(a) >= sz(b); } }; void solve() { s
int sz(int const & n) {
return __builtin_popcount(n);
}
struct comp {
bool operator()(int const & a, int const & b) const {
return sz(a) >= sz(b);
}
};
void solve() {
set<int, comp> s;
for (int i = 0; i < 10; ++i)
s.insert(i);
for (int x : s)
cerr << x << " ";
cerr << "\n";
for (int i = 0; i < 10; ++i)
cerr << s.count(i) << " ";
}
如何将std::set与自定义比较器一起使用,以确保所有操作都能正常工作?
提前谢谢。试试换衣服
struct comp {
bool operator()(int const & a, int const & b) const {
return sz(a) >= sz(b);
}
};
与
第一个问题是,比较器必须施加严格的弱排序
因此,特别是对于std::set
中的每个a
,必须是comp(a,a)=false
使用比较器,每个a
都有comp(a,a)=true
无论如何:仅当a!=b
s(a)!=s(b)
;如果不是这样的话。。。好。。。我想你可以试试这个
struct comp {
bool operator()(int const & a, int const & b) const {
return (sz(a) > sz(b)) || ((sz(a) == sz(b)) && (a > b));
}
};
或者类似的东西。试着改变一下
struct comp {
bool operator()(int const & a, int const & b) const {
return sz(a) >= sz(b);
}
};
与
第一个问题是,比较器必须施加严格的弱排序
因此,特别是对于std::set
中的每个a
,必须是comp(a,a)=false
使用比较器,每个a
都有comp(a,a)=true
无论如何:仅当a!=b
s(a)!=s(b)
;如果不是这样的话。。。好。。。我想你可以试试这个
struct comp {
bool operator()(int const & a, int const & b) const {
return (sz(a) > sz(b)) || ((sz(a) == sz(b)) && (a > b));
}
};
或者类似的东西。根据cppreference.com: 一种二进制谓词,它接受两个与元素类型相同的参数并返回布尔值。表达式comp(a,b),其中comp是此类型的对象,a和b是键值,如果在函数定义的严格弱顺序中a被认为在b之前,则应返回true
您的比较器不会这样做。根据cppreference.com: 一种二进制谓词,它接受两个与元素类型相同的参数并返回布尔值。表达式comp(a,b),其中comp是此类型的对象,a和b是键值,如果在函数定义的严格弱顺序中a被认为在b之前,则应返回true
您的比较器不会这样做。更多关于理论方面的内容: 根据for
std::set
的比较器(以及标准库中每隔一个“小于比较器”),它需要建立一个:
- 对于所有
,a
comp(a,a)=false
- 如果
则comp(a,b)==true
comp(b,a)==false
- 如果
和comp(a,b)==true
则comp(b,c)==true
comp(a,c)==true
equiv
表达式处理的,但请注意,以上三个还不够
您可以将比较视为询问“必须a
在b
之前出现?”实现假设这是比较所询问的问题,对于相等元素的回答是否,一个元素不得出现在另一个元素之前。您的比较器未通过前两项测试:
返回comp(0,0)
true
返回comp(1,2)
,但true
返回comp(2,1)
false
3 1
并希望插入2
。从开头开始,您检查comp(2,1)
。它返回true
,因为两者的位数相同,所以您完成了,现在您有了2 3 1
。显然,这是错误的。这并不是说std::set
与排序数组相同,但在确定元素的放置和查找位置时,它需要进行一些操作。严格的弱排序使该过程保持一致
对于递减的popcount排序,您真正想要的是严格意义上的大于比较。因此,变化是微不足道的:
return sz(a) > sz(b);
更多关于理论方面的内容: 根据for
std::set
的比较器(以及标准库中每隔一个“小于比较器”),它需要建立一个:
- 对于所有
,a
comp(a,a)=false
- 如果
则comp(a,b)==true
comp(b,a)==false
- 如果
和comp(a,b)==true
则comp(b,c)==true
comp(a,c)==true
equiv
表达式处理的,但请注意,以上三个还不够
您可以将比较视为询问“必须a
在b
之前出现?”实现假设这是比较所询问的问题,对于相等元素的回答是否,一个元素不得出现在另一个元素之前。您的比较器未通过前两项测试:
返回comp(0,0)
true
返回comp(1,2)
,但true
返回comp(2,1)
false
3 1
并希望插入2
。从开头开始,您检查comp(2,1)
。它返回true
,因为两者的位数相同,所以您完成了,现在您有了2 3 1
。显然,这是错误的。这并不是说std::set
与排序数组相同,但在确定元素的放置和查找位置时,它需要进行一些操作。严格的弱排序使该过程保持一致
对于递减的popcount排序,您真正想要的是严格意义上的大于比较。因此,变化是微不足道的:
return sz(a) > sz(b);
您的比较器没有严格的弱排序<代码>cmp(a,b)意味着
!cmp(b,a)
,但如果sz(a)=sz(b)
,则您的比较器将为这两个值返回true。甚至