【发布时间】:2018-08-25 05:57:25
【问题描述】:
我在某些类型 T 上存在二元关系,该类型由函数 equivalent 引起:
bool equivalent(T const& a, T const& b); // returns true if a and b are equivalent
它具有的特性
equivalent(a, a) == true
和
equivalent(a, b) == equivalent(b, a)
对于所有a、b。
对于T 类型的给定元素集合,我想删除每个等价类的第一次出现以外的所有元素。我想出了以下代码,但一直在徘徊:
有没有不显式循环的解决方案?
std::vector<T> filter_all_but_one_for_each_set_of_equivalent_T(std::vector<T> const& ts) {
std::vector<T> result;
for (auto iter = ts.begin(); iter != ts.end(); ++iter) {
auto const& elem = *iter;
bool has_equivalent_element_at_earlier_position = std::any_of(
ts.begin(),
iter,
&equivalent
);
if (not has_equivalent_element_at_earlier_position) {
result.push_back(routing_pin);
}
}
return result;
}
更新
据我了解,std::unique 不会这样做,因为我的类型 T 不可排序。而且因为我只有 C++11,但我也会对其他教育选项感兴趣。
【问题讨论】:
-
是的,但更重要的是:“从范围内的每个等效元素的连续组中消除除第一个元素之外的所有元素......”在我的情况下,等效元素是分散的在整个集合中,因此如果可以的话,你会事先对它们进行排序。
-
任何评论
std::unique不需要排序的人。出于 OP 的目的,它确实如此。aabbccaa之类的东西会变成abca,而不是abc,但后者是 OP 需要的。 -
仅供参考,等价关系是可传递的,也就是说,
equiv(a,b)&&equiv(b,c)意味着equiv(a,c)。 -
@Elrond1337 您在下面的 cmets 中的示例不是传递性
-
算法为什么要依赖我的等价关系的细节?我要问的是该算法适用于与
operator<不可比较但与equivalent或operator==是等价关系的类型。如果我错了并且它不是等价关系,那么代码就会被破坏,但这不是你的问题。