使用标准库根据一个数组对两个数组进行排序(避免复制步骤)
Posted
技术标签:
【中文标题】使用标准库根据一个数组对两个数组进行排序(避免复制步骤)【英文标题】:Sorting two arrays based on one with standard library (copy steps avoided) 【发布时间】:2017-05-17 14:32:46 【问题描述】:我有旧代码要维护,我正在替换一个自定义 QuickSort,该 QuickSort 使用 std::sort 根据数组 1 对两个数组进行排序。有没有一种方法可以根据其中一个数组对两个数组进行排序,而无需额外的拆分步骤并且无需再次实现排序功能?下面是当前示例 vector1D 基本上是 std::vector。
vector1D<std::pair<int64_t, uint8_t>> m_RowCol(m_NX * m_NY * m_NZ);
//..
std::sort(
m_RowCol.begin(),
m_RowCol.end(),
[](const std::pair<int64_t, uint8_t> &a, const std::pair<int64_t, uint8_t> &b) return a.first < b.first && (a.first > 0 && b.first > 0);
);
// copy into two vectors
vector1D<int64_t> m_Row;
vector1D<uint8_t> m_Col;
for (auto it = std::make_move_iterator(m_RowCol.begin()), end = std::make_move_iterator(m_RowCol.end()); it != end; ++it)
m_Row.push_back(std::move(it->first));
m_Col.push_back(std::move(it->second));
m_RowCol.clear();
【问题讨论】:
见***.com/questions/13840998/… 请注意,尽管您的比较器不满足严格的弱排序要求,但您的程序会表现出未定义的行为。具体来说,0等价于1,0等价于2,但1不等价于2。 @Igor 谢谢你 我想避免使用第 3 方库。 Boost 可能会起作用。 你更新的比较器仍然有同样的问题。 【参考方案1】:您可以创建一个索引数组,根据其中一个数组对索引进行排序,然后在 O(n) 时间内根据排序后的索引数组对两个数组和索引数组重新排序:
#include <algorithm>
#include <iostream>
int main()
int A[8] = 8,6,1,7,5,3,4,2;
char B[8] = 'h','f','a','g','e','c','d','b';
size_t I[8];
size_t i, j, k;
int ta;
char tb;
// create array of indices to A[]
for(i = 0; i < sizeof(A)/sizeof(A[0]); i++)
I[i] = i;
// sort array of indices to A[]
std::sort(I, I+sizeof(I)/sizeof(I[0]),
[&A](int i, int j) return A[i] < A[j];);
// reorder A[] B[] I[] according to I[]
for(i = 0; i < sizeof(A)/sizeof(A[0]); i++)
if(i != I[i])
ta = A[i];
tb = B[i];
k = i;
while(i != (j = I[k]))
A[k] = A[j];
B[k] = B[j];
I[k] = k;
k = j;
A[k] = ta;
B[k] = tb;
I[k] = k;
for(i = 0; i < sizeof(A)/sizeof(A[0]); i++)
std::cout << A[i] << ' ';
std::cout << std::endl;
for(i = 0; i < sizeof(B)/sizeof(B[0]); i++)
std::cout << B[i] << ' ';
std::cout << std::endl;
return 0;
或者可以使用指针数组代替索引数组,这样就可以使用普通的比较函数而不是 lambda 比较函数。
#include <algorithm>
#include <iostream>
bool compare(const int *p0, const int *p1)
return *p0 < *p1;
int main()
int A[8] = 8,6,1,7,5,3,4,2;
char B[8] = 'h','f','a','g','e','c','d','b';
int *pA[8];
size_t i, j, k;
int ta;
char tb;
// create array of pointers to A[]
for(i = 0; i < sizeof(A)/sizeof(A[0]); i++)
pA[i] = &A[i];
// sort array of pointers to A[]
std::sort(pA, pA+sizeof(A)/sizeof(A[0]), compare);
// reorder A[] B[] pA[] according to pA[]
for(i = 0; i < sizeof(A)/sizeof(A[0]); i++)
if(i != pA[i]-A)
ta = A[i];
tb = B[i];
k = i;
while(i != (j = pA[k]-A))
A[k] = A[j];
B[k] = B[j];
pA[k] = &A[k];
k = j;
A[k] = ta;
B[k] = tb;
pA[k] = &A[k];
for(i = 0; i < sizeof(A)/sizeof(A[0]); i++)
std::cout << A[i] << ' ';
std::cout << std::endl;
for(i = 0; i < sizeof(B)/sizeof(B[0]); i++)
std::cout << B[i] << ' ';
std::cout << std::endl;
return 0;
【讨论】:
以上是关于使用标准库根据一个数组对两个数组进行排序(避免复制步骤)的主要内容,如果未能解决你的问题,请参考以下文章