Sorting two arrays based on one with standard library (copy steps avoided)

前端 未结 1 865
爱一瞬间的悲伤
爱一瞬间的悲伤 2020-12-04 03:32

I have old code to maintain and I was replacing a custom QuickSort which was sorting two arrays based on array one with std::sort. Is there a way to sort two arrays based on

相关标签:
1条回答
  • 2020-12-04 04:06

    You can create an array of indices, sort the indices according to one of the arrays, then reorder the two arrays and array of indices in place according to the sorted array of indices in O(n) time:

    #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;
    }
    

    or an array of pointers can be used instead of an array of indices, which allows a normal compare function instead of a lambda compare function.

    #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;
    }
    
    0 讨论(0)
提交回复
热议问题