排序两个相应的数组

rec*_*gle 23 c++ arrays

我这里的代码有两个数组.它对arr []进行排序,因此最高值将在索引0中.现在第二个数组arr1 []包含字符串,我希望代码将arr []所做的任何更改应用于arr1 [].因此arr [0]将返回6,而arr1 [0]将返回字符串"d1".请注意"d1"6的索引是否相同?排序后我想要相同的值仍然有他们的字符串对应物.

我该怎么做呢?

#include <iostream>
#include <iomanip>
#include <algorithm>
#include <functional>
using namespace std;

int main() {
  int arr[ 5 ] = { 4, 1, 3, 6, 2 };  
  string arr1[ 5 ] = { "a1", "b1", "c1", "d1", "e1" };

  std::sort( arr, arr + 5, std::greater< int >() );
  cout << arr[0] << arr1[0] << endl;

  system("pause");
}
Run Code Online (Sandbox Code Playgroud)

mik*_*ked 32

而不是对数组进行排序,对索引进行排序.即,你有

int arr[5]={4,1,3,6,2}
string arr1[5]={"a1","b1","c1","d1","e1"};
Run Code Online (Sandbox Code Playgroud)

而你做

int indices[5]={0,1,2,3,4};
Run Code Online (Sandbox Code Playgroud)

现在你做一个看起来像这样的排序索引比较器(只是想法,你可能需要修改一下)

class sort_indices
{
   private:
     int* mparr;
   public:
     sort_indices(int* parr) : mparr(parr) {}
     bool operator()(int i, int j) const { return mparr[i]<mparr[j]; }
}
Run Code Online (Sandbox Code Playgroud)

现在你可以使用stl排序了

std::sort(indices, indices+5, sort_indices(arr));
Run Code Online (Sandbox Code Playgroud)

当你完成后,indices数组将arr[indices[0]]是第一个元素.同样arr1[indices[0]]是相应的一对.

当您尝试对大型数据对象进行排序时,这也是一个非常有用的技巧,您不需要在每次交换时只移动数据,只需要移动数据.

  • 请注意,如果您确实需要对两个数组进行排序,那么使用索引数组将原始数组按顺序排列并非完全无关紧要. (7认同)
  • @rint:这几乎是微不足道的,但我会说不完全是。在示例中,数组属于可复制分配的类型。情况总是如此,这并非微不足道:-) 此外,使用第二个数组可能比单独使用 `std::sort` 需要更多的内存。因此,移到第二个数组然后移回写入是微不足道的,但不是最佳的,您可能会或可能不会关心。 (3认同)

Pet*_*der 10

您需要将它们组合在一起,然后对组合对进行排序,然后取消组合对.

int arr[ 5 ] = { ... };
string arr1[ 5 ] = { ... };
pair<int, string> pairs[ 5 ];

for ( int i = 0; i < 5; ++i )
  pairs[ i ] = make_pair( arr[ i ], arr1[ i ] );

sort( pairs.begin(), pairs.end() );

for ( int i = 0; i < 5; ++i )
{
  arr[ i ] = pairs[ i ].first;
  arr1[ i ] = pairs[ i ].second;
}
Run Code Online (Sandbox Code Playgroud)

真的不过,如果arrarr1相关那么它们应该被存储为pair(或至少一个自定义struct反正).这样您就不需要将其用作中间步骤.


Jef*_*ung 6

编写自己的迭代器并使用STD:sort.没有第三方库,它可以在不到50行中轻松编码.交换功能在这里非常重要.

#include <iostream>
#include <iterator>     // std::iterator, std::input_iterator_tag
#include <algorithm>

using namespace std;

struct Tuple;
struct RefTuple;
#define TUPLE_COMMON_FUNC(C, D, E, F)            \
    C##::C## (Tuple& t) ##D                        \
    C##::C## (RefTuple& t) ##D                    \
    void C##::operator = (Tuple& t) ##E        \
    void C##::operator = (RefTuple& t) ##E    \
    bool C##::operator < (const Tuple& t) const ##F        \
    bool C##::operator < (const RefTuple& t) const ##F
#define ASSIGN_1    : i(t.i), j(t.j), s(t.s) {}
#define ASSIGN_2    { i = t.i; j = t.j; s = t.s; }
#define SORT_CRITERIA \
    return (j < t.j) || (j == t.j && (i < t.i));
struct Tuple {
    int i, j, s;
    TUPLE_COMMON_FUNC(Tuple, ; , ; , ;)
};
struct RefTuple {
    int &i, &j, &s;
    RefTuple(int &x, int &y, int &z): i(x), j(y), s(z) {}
    TUPLE_COMMON_FUNC(RefTuple, ; , ; , ;)
};
TUPLE_COMMON_FUNC(Tuple, ASSIGN_1, ASSIGN_2, {SORT_CRITERIA})
TUPLE_COMMON_FUNC(RefTuple, ASSIGN_1, ASSIGN_2, {SORT_CRITERIA})

void swap(RefTuple& t1, RefTuple& t2) {
    t1.i ^= t2.i; t2.i ^= t1.i; t1.i ^= t2.i;
    t1.j ^= t2.j; t2.j ^= t1.j; t1.j ^= t2.j;
    t1.s ^= t2.s; t2.s ^= t1.s; t1.s ^= t2.s;
}

class IterTuple : public iterator<random_access_iterator_tag, Tuple> {
    int *i, *j, *s, idx;
public:
    IterTuple(int* x, int*y, int* z, int l) : i(x), j(y), s(z), idx(l) {}
    IterTuple(const IterTuple& e) : i(e.i), j(e.j), s(e.s), idx(e.idx) {}
    RefTuple operator*() { return RefTuple(i[idx], j[idx], s[idx]);  }
    IterTuple& operator ++ () { idx++; return *this; }
    IterTuple& operator -- () { idx--; return *this; }
    IterTuple operator ++ (int) { IterTuple tmp(*this); idx++; return tmp; }
    IterTuple operator -- (int) { IterTuple tmp(*this); idx--; return tmp; }
    int operator - (IterTuple& rhs) { return idx - rhs.idx;    }
    IterTuple operator + (int n) { IterTuple tmp(*this); tmp.idx += n; return tmp; }
    IterTuple operator - (int n) { IterTuple tmp(*this); tmp.idx -= n; return tmp; }
    bool operator==(const IterTuple& rhs) {        return idx == rhs.idx;    }
    bool operator!=(const IterTuple& rhs) {     return idx != rhs.idx;  }
    bool operator<(IterTuple& rhs) {     return idx < rhs.idx;   }
};

int Ai[10] = {0, 0, 2, 3, 2, 4, 1, 1, 4, 2};
int Aj[10] = {0, 2, 3, 4, 4, 4, 0, 1, 0, 2};
int Ax[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};

int main () {
    IterTuple from(Ai, Aj, Ax, 0);
    IterTuple until(Ai, Aj, Ax, 10);

    sort(from, until);

    for (IterTuple it = from; it != until; it++)
        cout << (*it).i << ' ' << (*it).j << ' ' << (*it).s << '\n';

    return 0;
}
Run Code Online (Sandbox Code Playgroud)