23. oktober 2004 - 00:42
Der er
12 kommentarer og 1 løsning
STL sort med keys og items
Hvis man har en array eller STL-vector a kan man sortere den med: std::sort(a,a+len); Mit spørgsmål er: hvis man har to arrays key og item, og gerne vil sortere dem begge (hvor key bestemmer rækkefølgen). Hvordan gør man det med STL?
Annonceindlæg fra Infor
23. oktober 2004 - 00:50
#1
Måske: #include <iostream> #include <algorithm> #include <vector> class StoreClass { public: StoreClass(std::string aName, int aVal) : Name(aName), Val(aVal) {} std::string Name; int Val; }; class CompareClass { public: bool operator () (const StoreClass &lhs, const StoreClass &rhs) { return lhs.Name < rhs.Name; } }; std::vector<StoreClass > MyVector; int main() { MyVector.push_back(StoreClass("Ole", 12)); MyVector.push_back(StoreClass("Anders", 21)); MyVector.push_back(StoreClass("Peter", 32)); std::vector<StoreClass >::size_type i; for(i = 0; i < MyVector.size(); i++) std::cout << MyVector[i].Name << " " << MyVector[i].Val << std::endl; CompareClass Compare; std::sort(MyVector.begin(), MyVector.end(), Compare); for(i = 0; i < MyVector.size(); i++) std::cout << MyVector[i].Name << " " << MyVector[i].Val << std::endl; }
23. oktober 2004 - 01:08
#2
Jeg kender ikke en metode til at sortere to arrays/vectors/containers på een gang.
23. oktober 2004 - 02:07
#3
Man kunne måske også: #include <iostream> #include <algorithm> #include <vector> #include <map> #include <string> std::vector<std::string > MyVector1; std::vector<int > MyVector2; int main() { MyVector1.push_back("Ole"); MyVector1.push_back("Anders"); MyVector1.push_back("Peter"); MyVector2.push_back(12); MyVector2.push_back(1); MyVector2.push_back(3); std::map<std::string, int> Temp; std::vector<std::string >::size_type i; for(i = 0; i < MyVector1.size(); i++) Temp.insert(std::make_pair(MyVector1[i], MyVector2[i])); MyVector1.clear(); MyVector2.clear(); std::map<std::string, int>::iterator it; for(it = Temp.begin(); it != Temp.end(); ++it) { MyVector1.push_back(it->first); MyVector2.push_back(it->second); } for(i = 0; i < MyVector1.size(); i++) std::cout << MyVector1[i] << " " << MyVector2[i] << std::endl; }
23. oktober 2004 - 10:56
#4
Mange tak!
23. oktober 2004 - 10:58
#5
Jeg er ny her. Hvordan giver jeg dig dine 30 points?
23. oktober 2004 - 15:25
#6
Man kan ikke give point til kommentarer, kun til svar. Men jeg vil ikke have point, så jeg laver ikke svar. Hvis du har fået løst dit problem, laver du selv et svar som du derpå accepterer, så får du pointene tilbage.
23. oktober 2004 - 16:43
#7
:)
23. oktober 2004 - 20:16
#8
Hvis betingelsen er at man skal bruge std::sort, så har Bertel på glimrende vis beskrvet mulighederne. Men jeg mener ikke at det er smart at brueg std::sort i dette tilfælde. Man kan sagtens løse opgaven uden brug af nye STL strukturer, hvis man er villig til selv at skrive sorterings algoritmen. To eksempler: #include <iostream> #include <string> #include <cstdlib> #include <ctime> using namespace std; template<class T> void qsix(int n1,int n2,T *a,int *ix) { int l=n1; int r=n2; T pivot=a[ix[(n1+n2)/2]]; do { while(a[ix[l]]<pivot) l++; while(a[ix[r]]>pivot) r--; if(l<=r) { int tmp=ix[l]; ix[l]=ix[r]; ix[r]=tmp; l++; r--; } } while(l<=r); if(n1<r) qsix(n1,r,a,ix); if(l<n2) qsix(l,n2,a,ix); return; } template<class T1,class T2> void qs2(int n1,int n2,T1 *a,T2 *b) { int l=n1; int r=n2; T1 pivot=a[(n1+n2)/2]; do { while(a[l]<pivot) l++; while(a[r]>pivot) r--; if(l<=r) { T1 tmp1=a[l]; a[l]=a[r]; a[r]=tmp1; T2 tmp2=b[l]; b[l]=b[r]; b[r]=tmp2; l++; r--; } } while(l<=r); if(n1<r) qs2(n1,r,a,b); if(l<n2) qs2(l,n2,a,b); return; } const int N = 10; int main() { srand(time(NULL)); int ia[N]; string sa[N]; char tmp[2]; tmp[1] = '\0'; for(int i=0;i<N;i++) { ia[i] = rand(); tmp[0] = 'A' + i; sa[i] = tmp; } cout << "Usorteret:" << endl; for(int i=0;i<N;i++) { cout << ia[i] << " " << sa[i] << endl; } int ix[N]; for(int i=0;i<N;i++) ix[i]=i; qsix<int>(0,N-1,ia,ix); cout << "Sorteret med index:" << endl; for(int i=0;i<N;i++) { cout << ia[ix[i]] << " " << sa[ix[i]] << endl; } qs2<int,string>(0,N-1,ia,sa); cout << "Sorteret med 2 arrays:" << endl; for(int i=0;i<N;i++) { cout << ia[i] << " " << sa[i] << endl; } return 0; }
23. oktober 2004 - 23:54
#9
En glimrende løsning, man kunne overveje at bruge swap:
http://www.sgi.com/tech/stl/swap.html Spørgsmålet er måske om det ikke var bedre at have de to arrays som ét array, det kommer naturligvis an på opgaven.
23. oktober 2004 - 23:59
#10
Normalt vil man forvente at OOA&D vil føre til et array af objekter med 2 felter fremfor 2 arrays. Men man kan sagtens forestille sig situationer hvor 2 arrays er givet, fordi noget eksisterende kode leverer det ene array eller forventer det ene array.
28. oktober 2004 - 01:06
#11
En noget anderledes løsning (med lidt hjælp fra en kollega): Ar1 er Key, Ar2 Item. #include <vector> #include <algorithm> #include <iostream> class SortClass { public: SortClass(int *aArr) : Arr(aArr) { } bool operator () (const int &lhs, const int &rhs) { return Arr[lhs] < Arr[rhs]; } int *Arr; }; int main() { int Ar1[8] = { 6, 2, 7, 9, 11, 1, 66, 5}; char *Ar2[8] = {"Hans", "Grete", "Ole", "Peter", "Niels", "Keld", "Hanne", "Lars"}; int Temp[8]; int i; for(i = 0; i < 8; i++) Temp[i] = i; SortClass Sort(Ar1); std::sort(Temp, Temp + 8, Sort); std::sort(Ar1, Ar1 + 8); for(i = 0; i < 8; i++) { if(i < Temp[i]) { std::swap(Ar2[i], Ar2[Temp[i]]); *std::find(Temp, Temp + 8, i) = Temp[i]; } } for(i = 0; i < 8; i++) std::cout << Ar1[i] << " " << Ar2[i] << std::endl; return 0; }
28. oktober 2004 - 20:25
#12
Faktisk er det min qsix lavet med std::sort. Ses nemmere i denne her variant: #include <vector> #include <algorithm> #include <iostream> class SortClass { public: SortClass(int *aArr) : Arr(aArr) { } bool operator () (const int &lhs, const int &rhs) { return Arr[lhs] < Arr[rhs]; } int *Arr; }; int main() { int Ar1[8] = { 6, 2, 7, 9, 11, 1, 66, 5}; char *Ar2[8] = {"Hans", "Grete", "Ole", "Peter", "Niels", "Keld", "Hanne", "Lars"}; int Temp[8]; int i; for(i = 0; i < 8; i++) Temp[i] = i; SortClass Sort(Ar1); std::sort(Temp, Temp + 8, Sort); for(i = 0; i < 8; i++) std::cout << Ar1[Temp[i]] << " " << Ar2[Temp[i]] << std::endl; return 0; }
28. oktober 2004 - 20:36
#13
En anden model, hvor man slipper for at kalde find for hver element der skal flyttes. Den er måske optimal hvis listen er meget usorteret og elementerne i listen er små. #include <vector> #include <algorithm> #include <iostream> class SortClass { public: SortClass(int *aArr) : Arr(aArr) { } bool operator () (const int &lhs, const int &rhs) { return Arr[lhs] < Arr[rhs]; } int *Arr; }; int main() { int Ar1[8] = { 6, 2, 7, 9, 11, 1, 66, 5}; char *Ar2[8] = {"Hans", "Grete", "Ole", "Peter", "Niels", "Keld", "Hanne", "Lars"}; int Temp[8]; int i; for(i = 0; i < 8; i++) Temp[i] = i; SortClass Sort(Ar1); std::sort(Temp, Temp + 8, Sort); std::sort(Ar1, Ar1 + 8); char *Ar2Temp[8]; for(i = 0; i < 8; i++) Ar2Temp[i] = Ar2[Temp[i]]; for(i = 0; i < 8; i++) Ar2[i] = Ar2Temp[i]; for(i = 0; i < 8; i++) std::cout << Ar1[i] << " " << Ar2[i] << std::endl; return 0; }
Kurser inden for grundlæggende programmering