使用STL根据一个数组的值对两个数组进行排序

时间:2016-01-14 14:33:01

标签: c++ sorting stl

我想对两个数组a[]b[]进行排序,但问题是我想对ab进行排序,但仅取决于数组的值{{ 1}}。 使用STL的比较函数应该是什么?

a[]

按升序排序后:

a[5] = {4,5,2,10,1};
b[5] = {3,5,2,43,32};

我的意思是我不想对第二个数组进行排序,但希望它随着第一个数组的变化而改变。我想用STL。代码会是什么样的?我可以在没有STL的情况下完成。

2 个答案:

答案 0 :(得分:0)

你可以创建第三个指针数组,+ 0到a + length-1,使用只需知道[]中元素类型的比较,根据[]对指针进行排序,然后根据指针数组对[]和b []进行重新排序(在O(n)时间内)。

int a[8] = {7,5,0,6,4,2,3,1};
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[] and b[] according to the array of pointers to a[]
    // also reverts array of pointers back to a, a + size-1
    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;
        }
    }

// ...

bool compare(const int *p0, const int *p1)
{
    return *p0 < *p1;
}

您还可以使用索引0到length-1的数组,并使用Lambda比较来根据[]比较索引。此示例使用A [],B []和I []:

int A[8] = {7,5,0,6,4,2,3,1};
char B[8] = {'h','f','a','g','e','c','d','b'};
int I[8] = {0,1,2,3,4,5,6,7};
int tA;
char tB;
    // 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[] and B[] according to the array of indices to A[]
    // also restores I[] back to 0 to size-1
    for(int i = 0; i < sizeof(A)/sizeof(A[0]); i++){
        if(i != I[i]){
            tA = A[i];
            tB = B[i];
            int j;
            int 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;
        }
    }

答案 1 :(得分:0)

这不是完全无足轻重的,但这会奏效。这使用C ++ 11功能。

#include <vector>
#include <algorithm>

template<typename A1, typename A2> void sort_base(A1 begin1, A1 end1, A2 begin2)
{

     // deduce types of element values

     auto t1 = *begin1;
     auto t2 = *begin2;
     typedef decltype(t1) T1;
     typedef decltype(t2) T2;
     typedef std::pair<T1, T2> P;

     // copy and pack the data so we can sort it

     std::vector<P> temp(std::distance(begin1, end1));

     std::transform(begin1, end1, begin2, temp.begin(),
          [](const T1 &x, const T2 &y) {return std::make_pair(x,y);});

     std::sort(temp.begin(), temp.end(),
         [](const P &x, const P &y) {return x.first < y.first;});

     //   sorting done.  Unpack the data

     std::transform(temp.begin(), temp.end(), begin1,
         [](const P &x) {return x.first;});

     std::transform(temp.begin(), temp.end(), begin2,
         [](const P &x) {return x.second;});
}

int main()
{
    int a[5] = {4,5,2,10,1};
    double b[5] = {3,5,2,43,32};

    // output the arrays however you choose

    sort_base(std::begin(a), std::end(a), std::begin(b));

    // output the arrays however you choose
}

sort_base()函数(我从空中拔出的名字)确实假设begin2开始的范围(至少)与范围{{1}中的数字相同}}