【问题标题】:Is "dynamic comparator" available in C++C++ 中是否提供“动态比较器”
【发布时间】:2016-10-24 01:29:50
【问题描述】:

我正在寻找一个“动态比较器”,它根据运行时参数给出比较结果。

这是一个比较器,根据它们与输入参数 x 的距离来比较两个整数。

struct leq
{
    bool operator()(const int a, const int b, const int x) {
        return abs(a-x) <= abs(b-x);
    }
};

我希望用它来实现下面对一个包含整数2的集合的插入,也就是

mySet = {2}

mySet.insert(3, leq(5)) results: mySet = {3, 2} // argument x of leq is 5 and abs(3-5) < abs(2-5)

mySet.insert(3, leq(1)) results: mySet = {2, 3} // argument x of leq is 1 and abs(3-1) > abs(2-1)

Note: the argument x may change for each element to be inserted into mySet.

有没有办法只使用标准容器集及其成员函数来实现呢?

提前致谢!

【问题讨论】:

  • 当你写的时候你的实际问题是什么?
  • x 是每个std::set 实例的固定值吗?或者你想不时更改x的值?
  • 你要找的词是“有状态的”。
  • 可以为集合中的所有成员指定使用具有相同固定值x 的比较器函数的集合。也就是说,参数是在运行时指定的,但相同的x 值用于集合中的所有插入值。这与您展示的伪代码不完全一样,所以我暂缓回答,直到您澄清这是否正是您想要的。请注意,x 为 5,“2”和“7”将比较相等,我不清楚这是预期的结果。

标签: c++ set comparator


【解决方案1】:

你可以给你的比较器一个构造函数在运行时传递它的值:

struct leq
{
    const int x;
    leq(int x): x(x) {} // constructor

    bool operator()(const int a, const int b) const {
        return abs(a-x) < abs(b-x);
    }
};

// ...

// construct a set with a comparator set to x = 5
std::set<int, leq> my_set(leq(5)); 

【讨论】:

  • my_set.insert() 将使用 5 来插入要插入其中的所有元素,这不是我想要的(请参阅我修改后的注释)。我错过了什么吗?
  • @leo 不可能根据不同的标准订购不同的元素。我也看不出为什么std::set 是可取的。您需要一个允许任意排序元素的容器,例如 std::vector
【解决方案2】:

集合假定它们总是被排序的。所以他们的比较器不能安全地改变行为,除非改变与集合中每个现有的元素顺序一致。

最具活力的集合是:

template<class T>
using dynamic_set = std::set<T, std::function<bool(T const&,T const&)>>;

然后:

auto leq(int x){
  return [x](int a, int b){
    return abs(a-x) < abs(b-x);
  };
}

给我们leq

dynamic_set<int> mySet( {2}, leq(5) );
mySet.insert(3);

dynamic_set<int> mySet( {2}, leq(1) );
mySet.insert(3);

做你想做的,我相信。

auto 替换为leq 中的C++11 中的std::function&lt;bool(int const&amp;, int const&amp;)&gt;

【讨论】:

  • 我希望能够为要插入同一集合的每个元素使用不同的 x。您的解决方案似乎只允许对不同的集合使用不同的 x。
  • @leo 我的第一段是“集合假定它们总是排序的。所以它们的比较器不能安全地改变行为,除非改变与集合中的每个现有元素顺序一致。”什么不清楚?
猜你喜欢
  • 1970-01-01
  • 2015-05-11
  • 2015-09-08
  • 2015-12-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-15
  • 1970-01-01
相关资源
最近更新 更多