Così tanti hanno fatto questa domanda e nessuno ha trovato una risposta soddisfacente. Ecco un helper std :: sort che consente di ordinare due vettori contemporaneamente, tenendo conto dei valori di un solo vettore. Questa soluzione si basa su un costume RadomIt (iterator casuale), e opera direttamente sui dati vettoriali originali, senza copie temporanee, struttura riassetto o indici aggiuntivi:
namespace std {
namespace sort_helper {
template <typename _Data, typename _Order>
struct value_reference_t;
template <typename _Data, typename _Order>
struct value_t {
_Data data;
_Order val;
inline value_t(_Data _data, _Order _val) : data(_data), val(_val) {}
inline value_t(const value_reference_t<_Data,_Order>& rhs);
};
template <typename _Data, typename _Order>
struct value_reference_t {
_Data* pdata;
_Order* pval;
value_reference_t(_Data* _itData, _Order* _itVal) : pdata(_itData), pval(_itVal) {}
inline value_reference_t& operator = (const value_reference_t& rhs) { *pdata = *rhs.pdata; *pval = *rhs.pval; return *this; }
inline value_reference_t& operator = (const value_t<_Data,_Order>& rhs) { *pdata = rhs.data; *pval = rhs.val; return *this; }
inline bool operator < (const value_reference_t& rhs) { return *pval < *rhs.pval; }
};
template <typename _Data, typename _Order>
struct value_iterator_t :
iterator< random_access_iterator_tag, value_t<_Data,_Order>, ptrdiff_t, value_t<_Data,_Order>*, value_reference_t<_Data,_Order> >
{
_Data* itData;
_Order* itVal;
value_iterator_t(_Data* _itData, _Order* _itVal) : itData(_itData), itVal(_itVal) {}
inline ptrdiff_t operator - (const value_iterator_t& rhs) const { return itVal - rhs.itVal; }
inline value_iterator_t operator + (ptrdiff_t off) const { return value_iterator_t(itData + off, itVal + off); }
inline value_iterator_t operator - (ptrdiff_t off) const { return value_iterator_t(itData - off, itVal - off); }
inline value_iterator_t& operator ++() { ++itData; ++itVal; return *this; }
inline value_iterator_t& operator --() { --itData; --itVal; return *this; }
inline value_iterator_t operator ++ (int) { return value_iterator_t(itData++, itVal++); }
inline value_iterator_t operator -- (int) { return value_iterator_t(itData--, itVal--); }
inline value_t<_Data,_Order> operator *() const { return value_t<_Data,_Order>(*itData, *itVal); }
inline value_reference_t<_Data,_Order> operator *() { return value_reference_t<_Data,_Order>(itData, itVal); }
inline bool operator < (const value_iterator_t& rhs) const { return itVal < rhs.itVal; }
inline bool operator == (const value_iterator_t& rhs) const { return itVal == rhs.itVal; }
inline bool operator != (const value_iterator_t& rhs) const { return itVal != rhs.itVal; }
};
template <typename _Data, typename _Order>
inline value_t<_Data,_Order>::value_t(const value_reference_t<_Data,_Order>& rhs)
: data(*rhs.pdata), val(*rhs.pval) {}
template <typename _Data, typename _Order>
bool operator < (const value_t<_Data,_Order>& lhs, const value_reference_t<_Data,_Order>& rhs) {
return lhs.val < *rhs.pval; }
template <typename _Data, typename _Order>
bool operator < (const value_reference_t<_Data,_Order>& lhs, const value_t<_Data,_Order>& rhs) {
return *lhs.pval < rhs.val; }
template <typename _Data, typename _Order>
void swap(value_reference_t<_Data,_Order> lhs, value_reference_t<_Data,_Order> rhs) {
std::swap(*lhs.pdata, *rhs.pdata);
std::swap(*lhs.pval, *rhs.pval); }
} // namespace sort_helper
} // namespace std
e questo è un esempio di utilizzo che ordina sia Nomi e Età sulla base di Età valori, che impiegano di serie std :: sorta:
char* Names[] = { "Karl", "Paul", "Martin", "Jennie" };
int Age[] = { 45, 14, 5, 24 };
typedef std::sort_helper::value_iterator_t<char*,int> IndexIt;
std::sort(IndexIt(Names, Age), IndexIt(Names+4, Age+4));
ordinate per:
{ "Martin", "Paul", "Jennie", "Karl" };
{ 5, 14, 24, 45 };
codice testato su Visual Studio 2017 eGCC 5.4.0.
Perché non avere un 'std :: vector>' invece? –
O almeno crea una 'struct' con un' int' e una 'stringa' e un' vector' di quello. – DeiDei
Oppure ordina un vettore di indici 'std :: vector' fornendo un comparatore personalizzato 'comp (i, j): = Punteggio [i]