假设我有以下代码,用于对另一个数据结构中的数据结构的元素进行排序,但保留其原始索引的记录:
std::vector<int> numbers = {..};
std::vector<std::pair<int, std::vector<int>::size_type>> temp;
for (std::vector<int>::size_type i = 0; i < numbers.size(); i++)
{
temp.push_back({ numbers[i], i });
}
std::sort(temp.begin(), temp.end(), [](const auto& x, const auto& y) { return x.first < y.first; });
到目前为止一切顺利。但我真正想要的是将数据和索引存储在不同的数据结构中:
std::vector<int> sorted;
std::vector<std::vector<int>::size_type> indices;
使sorted[i]
处的元素位于原始数据结构中的索引indices[i]
。
除了推出我自己的排序算法,或者在事后分割数据结构之外,使用标准库有没有简单的技巧呢?
答案 0 :(得分:0)
我们的想法是将您的数据存储在一个容器中,并使其他容器具有索引(基于不同的排序标准)。
这里的想法是编写函数对象,根据排序条件和数据容器中的值比较两个索引。
下一步是将您的函数对象传递给适当的排序函数。
答案 1 :(得分:0)
澄清托马斯马修回答......创建索引0到n-1的向量。使用lambda函数根据数据向量对索引向量进行排序。示例代码包括可选的重新排序函数。
void reorder(std::vector<int>& vA, std::vector<size_t> vI);
int main()
{
std::vector <int> vdata = { 7,2,4,5,3,1,6,0 }; // original data
std::vector <size_t> vindex = { 0,1,2,3,4,5,6,7 }; // original indices
std::sort(vindex.begin(), vindex.end(), [&vdata](size_t i, size_t j)
{return vdata[i] < vdata[j];});
for (size_t i = 0; i < vdata.size(); i++)
std::cout << "[" << vindex[i] << "]=" << vdata[vindex[i]] << " ";
std::cout << std::endl;
reorder(vdata, vindex);
for (size_t i = 0; i < vdata.size(); i++)
std::cout << "[" << i << "]=" << vdata[i] << " ";
return 0;
}
// every move places an element in it's final location
// vI passed by value (copy)
void reorder(std::vector<int>& vA, std::vector<size_t> vI)
{
size_t i, j, k;
int tA;
for (i = 0; i < vA.size(); i++) {
if (i != vI[i]) {
tA = vA[i];
k = i;
while (i != (j = vI[k])) {
vA[k] = vA[j];
vI[k] = k;
k = j;
}
vA[k] = tA;
vI[k] = k;
}
}
}