2010-10-11 13 views
20

मेरे पास यह कोड है जिसमें दो सरणी हैं। यह arr [] है, ताकि उच्चतम मान सूचकांक 0 में होगा। अब दूसरी सरणी arr1 [] स्ट्रिंग्स है, मैं कोड को arr [] पर किए गए परिवर्तनों को लागू करने के लिए चाहता हूं arr1 []। तो arr [0] 6 लौटाएगा, जबकि arr1 [0] स्ट्रिंग "d1" वापस करेगा। ध्यान दें कि "डी 1" के समान सूचकांक में था? सॉर्ट करने के बाद मैं वही मानों को अभी भी अपने स्ट्रिंग समकक्षों के पास रखना चाहता हूं।दो संबंधित सरणी छंटनी

मैं यह करने के बारे में कैसे जाउंगा?

#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

एक बार जब आप मूल क्रम क्रम को 'arr' क्रमबद्ध करते हैं तो अब ज्ञात नहीं है। यदि आप सरल असाइनमेंट द्वारा अन्य सरणी को सॉर्ट करना चाहते हैं तो आपको मूल ऑर्डर स्टोर करना होगा। –

+0

यदि 'arr' और' arr1' संबंधित हैं, तो वे पहले स्थान पर एक साथ क्यों संग्रहीत नहीं होते हैं (संरचना के रूप में कहते हैं)? – casablanca

+2

डुप्लिकेट: http://stackoverflow.com/questions/236172/how-do-i-sort-a-stdvector-by-the-values-of-a- अलग-stdvector –

उत्तर

25

सरणी को सॉर्ट करने के बजाय, इंडेक्स को सॉर्ट करें। यानी, आप

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

है और आप

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

कर अब आप एक तरह से सूचकांक तुलनित्र कि इस तरह दिखता है बनाने के

(बस और विचार, तो आप शायद यह थोड़ा ठीक करने के लिए करना होगा)
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]; } 
} 

अब आप एसटीएल तरह

std::sort(indices, indices+5, sort_indices(arr)); 
उपयोग कर सकते हैं

जब आप पूरा कर लेंगे, तो सूचकांक सरणी ऐसी होगी कि arr[indices[0]] पहला तत्व है। और इसी प्रकार arr1[indices[0]] संबंधित जोड़ी है।

यह एक बहुत ही उपयोगी चाल है जब आप एक बड़ी डेटा ऑब्जेक्ट को सॉर्ट करने का प्रयास कर रहे हैं, तो आपको प्रत्येक स्वैप पर केवल डेटा को स्थानांतरित करने की आवश्यकता नहीं है।

+0

मामूली बिंदु के अलावा अच्छा जवाब है कि वह अवरोही क्रमबद्ध है, लेकिन हाँ, यह करने का यह तरीका है। – CashCow

+0

हाँ, और ऑपरेटर() को भी काम करने के लिए इसके लिए आधार होना चाहिए।:) – miked

+5

ध्यान दें कि यदि आपको वास्तव में दो सरणी क्रमबद्ध करने की आवश्यकता है, तो मूल सरणी को क्रम में रखने के लिए सूचकांक की सरणी का उपयोग पूरी तरह से तुच्छ नहीं है। –

8

आपको उन्हें एक साथ जोड़ना होगा और फिर संयुक्त जोड़ी को सॉर्ट करना होगा और फिर जोड़ों को गठबंधन करना होगा।

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

सच हालांकि, अगर arr और arr1 तो संबंधित हैं वे pair (या कम से कम एक कस्टम struct) वैसे भी रूप में जमा किया जाना चाहिए। इस तरह आपको इसे मध्यवर्ती चरण के रूप में उपयोग करने की आवश्यकता नहीं है।

6

अपना खुद का इटरेटर लिखें और एसटीडी का उपयोग करें: क्रमबद्ध करें। यह आसानी से तीसरे पक्ष के पुस्तकालयों के बिना 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; 
} 
संबंधित मुद्दे