对一个矢量进行排序,其中拉链断裂元素被懒惰地计算

时间:2017-05-06 00:41:34

标签: c++

我想通过主要字段对结构的向量进行排序,并使用辅助字段作为打破平局。通常的方式是:

struct element {
  int primary;
  int secondary;
};

bool comparator(const element& e1, const element& e2) {
  if (e1.primary != e2.primary) {
    return e1.primary < e2.primary;
  }
  return e1.secondary < e2.secondary;
}

但是二级数据的计算成本很高。因为它仅在主值相等时才需要,我想懒惰地计算它。

似乎我唯一可以做这个懒惰评估的地方就是比较器本身。类似的东西:

bool comparator(const element& e1, const element& e2) {
  if (e1.primary != e2.primary) {
    return e1.primary < e2.primary;
  }

  return e1.computeSecondary() < e2.computeSecondary();
}

虽然这将避免在主值不同的情况下评估次要值,但每次与另一个元素进行比较时,它将最终重新计算同一元素的次要值。我想要排序的数据是长尾的,其中30%的值等于1,20%等于2,5%等于3,较高的值为%。因此,将会有相当多的情况会计算次要元素,而不存储计算值可能导致重新计算次数。

所以,我希望每个元素最多评估一次二次值。但是比较器采用const ref参数,因此它不能修改元素的二次值。如何实现这一目标?

1 个答案:

答案 0 :(得分:3)

简而言之,可能的选择。

  1. 声明secondary mutable。
  2. const_cast。{/ li>中使用comparator
  3. const_cast。{/ li>中使用computeSecondary
  4. 创建一个简单的Lazy模板类,该类可以包含值或thunk,并且在被要求时,如果尚未评估值,则在内部强制执行值并报告结果(或立即报告结果,如果它已经知道),不需要很长时间;并声明类型为secondary的{​​{1}}。
  5. 或者更确切地说,不要重新发明轮子并使用Lazy<int>实际上是非常懒惰的模板(在一种情况下)。
  6. 或者其他任何事情,都可以创造出更多的方法。