C++标准库提供了将Comparator传递给std::sort的功能。然而,在我的代码中,我有很多情况需要按照函数f对T对象的列表进行排序。像这样的比较器是一个有效的选择:
这样做并不是最优的。虽然计算
我的目标是编写这个函数(我还没有能够完成):
在此调用之后,对于序列left到right中的所有iter,都有f(*iter) <= f(*std::next(iter))。
此外,该函数应满足以下要求:
- 不会分配任何额外的T类型对象。 - 精确评估f std :: distance(left,right)次。 - 保持O(n log n)的总体复杂度。 - 应基于std :: sort实现。当然,我可以通过实现自己的合并排序来解决这个问题,但是我想避免这样做。
(首选C++11;C++14也可以)
bool compare(const T& a, const T& b) {
return f(a) < f(b);
}
这样做并不是最优的。虽然计算
f
很慢,但对于相同的T
对象,每次调用都会返回相同的值。因此,我更愿意为范围内的每个对象计算一次f
,然后使用这些结果来对它们进行排序。我的目标是编写这个函数(我还没有能够完成):
template <typename IterT, typename Transformation>
void sort(IterT left, IterT right, Transformation f) { /* ? */ }
在此调用之后,对于序列left到right中的所有iter,都有f(*iter) <= f(*std::next(iter))。
此外,该函数应满足以下要求:
- 不会分配任何额外的T类型对象。 - 精确评估f std :: distance(left,right)次。 - 保持O(n log n)的总体复杂度。 - 应基于std :: sort实现。当然,我可以通过实现自己的合并排序来解决这个问题,但是我想避免这样做。
(首选C++11;C++14也可以)
f(a)
的结果存储在对象a
中,并且只有当对象状态改变时才计算它呢? - Richard Crittenf(*iter)
只依赖于*iter
还是同时依赖于iter
? - Kerrek SBa
创建一个值范围f(a)
,同时也创建一个索引范围,然后根据预先计算好的f
值对这些索引进行排序。这样你就得到了将原始范围按照排序顺序排列的排列方式,所以你只需要应用该排列方式即可。 - Kerrek SBf
与类没有直接关系,只在某些用例中相关;因此我会在类中有一些成员,在许多代码片段中从未使用。除此之外,每次更改对象时,我都必须手动调用类似于“updateF”的东西。 - Andreas Tf
也有优点;它简化了逻辑并且可能在更广泛的范围内被重复使用。这取决于T
对于记忆化是否合适。 - Kerrek SB