【发布时间】:2011-05-17 13:44:19
【问题描述】:
我有这样的数据结构:
struct X {
float value;
int id;
};
一个向量(大小N(想想100000),按值排序(在程序执行期间保持不变):
std::vector<X> values;
现在,我想写一个函数
void subvector(std::vector<X> const& values,
std::vector<int> const& ids,
std::vector<X>& out /*,
helper data here */);
用传递的 ids 给出的 值 的排序子集填充 out 参数(大小 M N(大约是N的0.8倍),fast(内存不是问题,会重复做,所以建立lookuptables (函数参数中的 helper 数据)或仅执行一次的其他操作完全可以)。
到目前为止我的解决方案:
构建包含 id -> 在 values 中的偏移量的可查找表 lut(准备,所以运行时恒定)
创建std::vector<X> tmp,大小为N,填充无效的ID(线性N)
对于每个 id,将 values[lut[id]] 复制到 tmp[lut[id]](M 中的线性)
循环tmp,将项目复制到out(线性N)
这在 N 中是线性的(因为它比 M 大),但是临时变量和重复复制让我很烦。有没有比这更快的方法?请注意,M 将接近 N,因此 O(M log N) 的事情是不利的。
编辑:http://ideone.com/xR8Vp 是上述算法的示例实现,以使所需的输出清晰并证明它在线性时间内是可行的 - 问题是关于避免临时变量或以其他方式加速它的可能性,非线性的东西不会更快:)。
【问题讨论】:
-
tmp的目的是什么?它最初是从哪里来的?为什么不直接在out中构建输出而不使用任何中间临时对象? -
另外,您要构建的内容在您的问题中没有得到很好的描述。最初,您似乎说您需要大小为
M的输出。然而,您的算法在所有情况下都尝试构建大小为N的输出。那么,在完成之后,你想在out数组中得到什么? -
关于“tmp 来自哪里” - 我创建了它。关于“为什么我不直接在
out中构建它” - 我不知道事先将元素放在哪里,我不知道子向量中的位置。不,我的输出是大小M,它在 N 中只是线性的,因为我测试了 tmp 中的每个元素。是的,id值是唯一的。 -
第二个向量按
id排序并使用equal_range、copy和最后sort按值应该给你M log N复杂度。 -
这是我错过的一件事 - M 将非常接近 N,所以这将是不利的(对于非常稀疏的 id,这将是有利的)
标签: c++ sorting vector large-data