c++ - 使用标准库基于一个数组对两个数组进行排序(避免复制步骤)

标签 c++ algorithm c++11

我有旧代码需要维护,我正在替换自定义 QuickSort,它基于数组 1 对两个数组进行排序,并使用 std::sort。有没有一种方法可以根据其中一个数组对两个数组进行排序,而无需额外的拆分步骤并且无需再次实现排序功能?下面是当前示例 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(); 

最佳答案

您可以创建一个索引数组,根据其中一个数组对索引进行排序,然后在 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;
}

关于c++ - 使用标准库基于一个数组对两个数组进行排序(避免复制步骤),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44027808/

相关文章:

c++ - std::bind 重载决议

c++ - 制作一元运算符二进制

c++ - 排序函数中 'operator=' 不匹配

c++ - 要导出的 Base unique_ptr vector

C程序计算两个日期之间的天数

重复背包算法

algorithm - 使用排序算法

c++ - C++ 新手 - & 参数前面的符号

c++ - Eigen Library::如何从现有稀疏矩阵中创建 block 对角稀疏矩阵?

c++ - C++ 中 const list<t> 的迭代器