2010-10-11 18 views
20

Tengo este código aquí que tiene dos matrices. Ordena arr [], por lo que el valor más alto estará en el índice 0. Ahora la segunda matriz arr1 [] contiene cadenas, me gustaría que el código aplique los cambios realizados en arr [] a arr1 []. Para que arr [0] devolvería 6, mientras que arr1 [0] devolvería la cadena "d1". Observe que "d1" tenía el mismo índice que ? Después de ordenar, me gustaría que los mismos valores sigan teniendo sus homólogos de cadena.Ordenando dos matrices correspondientes

¿Cómo voy a ir haciendo esto?

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


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"); 
} 
+0

una vez que haya ordenado 'arr', el orden de clasificación original ya no se conoce. Tendrá que guardar el pedido original si desea ordenar el otro arreglo por simple asignación. –

+0

Si 'arr' y' arr1' están relacionados, ¿por qué no se almacenan juntos (digamos como una estructura) en primer lugar? – casablanca

+2

duplicado: http://stackoverflow.com/questions/236172/how-do-i-sort-a-stdvector-by-the-values-of-a-different-stdvector –

Respuesta

25

En lugar de ordenar las matrices, ordene los índices. Es decir, tiene

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

y haces

int indices[5]={0,1,2,3,4}; 

ahora a tomar un comparador índices de ordenación que se parece a esto (justo e idea, es probable que tenga que arreglar un poco)

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

ahora puede utilizar la STL tipo

std::sort(indices, indices+5, sort_indices(arr)); 

Cuando haya terminado, la matriz de índices será tal que arr[indices[0]] es el primer elemento. y asimismo arr1[indices[0]] es el par correspondiente.

Este es también un truco muy útil cuando se está tratando de resolver un objeto de datos de gran tamaño, que no es necesario para mover los datos a una velocidad cada intercambio, sólo los índices.

+0

Buena respuesta aparte del punto menor que él está ordenando descender, pero sí, esta es la manera de hacerlo. – CashCow

+0

Sí, y el operador() necesita ser const para que esto también funcione.:) – miked

+5

Tenga en cuenta que si realmente necesita las dos matrices ordenadas, el uso de la matriz de índices para ordenar las matrices originales no es del todo trivial. –

8

Necesita combinarlos juntos y luego ordenar el par combinado y luego des-combinar los pares.

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

Realmente sin embargo, si arr y arr1 se relacionan a continuación, que deben ser almacenados como el pair (o al menos una costumbre struct) de todos modos. De esta forma, no necesita usar esto como un paso intermedio.

6

Escriba su propio iterador y use STD: sort. Se codifica fácilmente en menos de 50 líneas sin bibliotecas de terceros. La función de intercambio ES MUY IMPORTANTE aquí.

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