aluckdog
您可以对std :: pair进行排序,而不仅仅是整数 - 第一个int是原始数据,第二个int是原始索引。然后提供一个只对第一个int进行排序的比较器。例:Your problem instance: v = [5 7 8]New problem instance: v_prime = [<5,0>, <8,1>, <7,2>]使用比较器对新问题实例进行排序:typedef std::pair<int,int> mypair;bool comparator ( const mypair& l, const mypair& r)
{ return l.first < r.first; }// forgetting the syntax here but intent is clear enough使用该比较器的st_ :: sort on v_prime的结果应该是:v_prime = [<5,0>, <7,2>, <8,1>]你可以通过遍历向量来剥离索引,从每个std :: pair中获取.second。
跃然一笑
我写了索引排序的通用版本。template <class RAIter, class Compare>void argsort(RAIter iterBegin, RAIter iterEnd, Compare comp,
std::vector<size_t>& indexes) {
std::vector< std::pair<size_t,RAIter> > pv ;
pv.reserve(iterEnd - iterBegin) ;
RAIter iter ;
size_t k ;
for (iter = iterBegin, k = 0 ; iter != iterEnd ; iter++, k++) {
pv.push_back( std::pair<int,RAIter>(k,iter) ) ;
}
std::sort(pv.begin(), pv.end(),
[&comp](const std::pair<size_t,RAIter>& a, const std::pair<size_t,RAIter>& b) -> bool
{ return comp(*a.second, *b.second) ; }) ;
indexes.resize(pv.size()) ;
std::transform(pv.begin(), pv.end(), indexes.begin(),
[](const std::pair<size_t,RAIter>& a) -> size_t { return a.first ; }) ;}除了用于接收已排序索引的索引容器之外,用法与std :: sort的用法相同。测试:int a[] = { 3, 1, 0, 4 } ;std::vector<size_t> indexes ;argsort(a, a + sizeof(a) / sizeof(a[0]), std::less<int>(), indexes) ;for (size_t i : indexes) printf("%d\n", int(i)) ;对于没有c ++ 0x支持的编译器,你应该得到2 1 0 3.将lamba表达式替换为类模板:template <class RAIter, class Compare> class PairComp {public:
Compare comp ;
PairComp(Compare comp_) : comp(comp_) {}
bool operator() (const std::pair<size_t,RAIter>& a,
const std::pair<size_t,RAIter>& b) const { return comp(*a.second, *b.second) ; } } ;并重写std :: sort asstd::sort(pv.begin(), pv.end(), PairComp(comp)()) ;