446,148 Members | 1,339 Online Need help? Post your question and get tips & solutions from a community of 446,148 IT Pros & Developers. It's quick & easy.

# sort and get index?

 P: n/a In matlab, the sort function returns two things: [a,b]=sort([5, 8, 7]) a = 5 7 8 b = 1 3 2 where a is the sorted result, and b is the corresponding index. Is there C++ code available to achieve this? Better compatible with STL vector. Thanks Jul 22 '05 #1
8 Replies

 P: n/a "b83503104" wrote... In matlab, the sort function returns two things: [a,b]=sort([5, 8, 7]) a = 5 7 8 b = 1 3 2 where a is the sorted result, and b is the corresponding index. Is there C++ code available to achieve this? Probably. You could simply sort pairs based on their 'first' members, then get the 'second' members (which you should set to ordinal numbers before sorting). V Jul 22 '05 #2

 P: n/a template struct index_cmp { index_cmp(const T arr) : arr(arr) {} bool operator()(const size_t a, const size_t b) const { return arr[a] < arr[b]; } const T arr; }; vector a; a.push_back(5); a.push_back(8); a.push_back(7); vector b; for (unsigned i = 0; i < a.size(); ++i) b.push_back(i); // b = [0, 1, 2] sort(b.begin(), b.end(), index_cmp&>(a)); // b = [0, 2, 1] then just offset into the a vector with the indices in b. I recomend just sorting the indices this way and not touching the a vector. Jul 22 '05 #3

 P: n/a b8*******@yahoo.com (b83503104) wrote in message In matlab, the sort function returns two things: [a,b]=sort([5, 8, 7]) a = 5 7 8 b = 1 3 2 where a is the sorted result, and b is the corresponding index. Is there C++ code available to achieve this? Better compatible with STL vector. Thanks There is no such way in C++. But you can build it yourself. Here is one suggestion: make your original vector { 5, 8, 7 }, make a vector of pointers { &orig, &orig, &orig }, sort the vector of pointers using std::sort of 3 arguments which should yield { &orig, &orig, &orig }. A second suggestion is: make your original vector a vector of pair as { {5,0}, {8,1}, {7,2} }, sort the vector using std::sort of 3 arguments which should yield { {5,0}, {7,2}, {8,1} }. The first way would look something like this: std::vector orig; orig.push_back(5); orig.push_back(7); orig.push_back(8); std::vector pointer; pointer.reserve(orig.size()); const int *const start = &orig; const int *const end = start + orig.size(); for (int * iter = start; iter != end; ++iter) pointer.push_back(iter); std::sort(pointer.begin(), pointer.end(), LessDereference()); where struct LessDereference { template bool operator()(const T * lhs, const T * rhs) const { return *lhs < *rhs; } }; To print the results, choose whatever option you want. There are many ways, and here is one: for (int i=0; i

 P: n/a b8*******@yahoo.com (b83503104) wrote in message In matlab, the sort function returns two things: [a,b]=sort([5, 8, 7]) a = 5 7 8 b = 1 3 2 where a is the sorted result, and b is the corresponding index. Is there C++ code available to achieve this? Better compatible with STL vector. Thanks There is no such way in C++. But you can build it yourself. Here is one suggestion: make your original vector { 5, 8, 7 }, make a vector of pointers { &orig, &orig, &orig }, sort the vector of pointers using std::sort of 3 arguments which should yield { &orig, &orig, &orig }. A second suggestion is: make your original vector a vector of pair as { {5,0}, {8,1}, {7,2} }, sort the vector using std::sort of 3 arguments which should yield { {5,0}, {7,2}, {8,1} }. The first way would look something like this: std::vector orig; orig.push_back(5); orig.push_back(7); orig.push_back(8); std::vector pointer; pointer.reserve(orig.size()); const int *const start = &orig; const int *const end = start + orig.size(); for (int * iter = start; iter != end; ++iter) pointer.push_back(iter); std::sort(pointer.begin(), pointer.end(), LessDereference()); where struct LessDereference { template bool operator()(const T * lhs, const T * rhs) const { return *lhs < *rhs; } }; To print the results, choose whatever option you want. There are many ways, and here is one: for (int i=0; i

 P: n/a an*****************@yahoo.com (Me) wrote in message template struct index_cmp { index_cmp(const T arr) : arr(arr) {} bool operator()(const size_t a, const size_t b) const { return arr[a] < arr[b]; } const T arr; }; Maybe class index_cmp could hold a const reference rather than an object (ie. change const T arr to const T& arr). Saves unnecessary copying. sort(b.begin(), b.end(), index_cmp&>(a)); You can provide rename index_cmp to index_cmp_t and provide an inline function template inline index_cmp_t index_cmp(const Container& c) { return index_cmp_t(c); } This prevents the need to explicitly qualify template parameters in the code. Jul 22 '05 #6

 P: n/a "b83503104" wrote in message news:73**************************@posting.google.c om... In matlab, the sort function returns two things: [a,b]=sort([5, 8, 7]) a = 5 7 8 b = 1 3 2 where a is the sorted result, and b is the corresponding index. Is there C++ code available to achieve this? Better compatible with STL vector. Thanks Try the following untested code after installing boost from www.boost.org. #include #include #include typedef std::map tMap; // tMap Map; int Data[] = { 5, 8, 7 }; std::transform( &data, &data , boost::counting_iterator(1) , std::inserter(Map) , boost::bind( std::make_pair, _1, _2 ) ); for( tMap::const_iterator lItr = Map.begin() ; lItr != Map.end() ; ++lItr ) { std::cout << "Data Value: " << lItr->first << " At Index: " << lItr->second; } Jeff F Jul 22 '05 #7

 P: n/a > Maybe class index_cmp could hold a const reference rather than an object (ie. change const T arr to const T& arr). Saves unnecessary copying. sort(b.begin(), b.end(), index_cmp&>(a)); It does hold a const reference (notice the '&' at the call to sort). I did it this way because doing it the way I would do in real life (add a reference only if T isn't a pointer or a reference) requires a lot more code or a dependency on boost's type_traits (which will hopefully be added to the next standard). Jul 22 '05 #8

 P: n/a an*****************@yahoo.com (Me) wrote in message Maybe class index_cmp could hold a const reference rather than an object (ie. change const T arr to const T& arr). Saves unnecessary copying. sort(b.begin(), b.end(), index_cmp&>(a)); It does hold a const reference (notice the '&' at the call to sort). I did it this way because doing it the way I would do in real life (add a reference only if T isn't a pointer or a reference) requires a lot more code or a dependency on boost's type_traits (which will hopefully be added to the next standard). Good point, sorry missed it. Jul 22 '05 #9

### This discussion thread is closed

Replies have been disabled for this discussion. 