C++ sorting and keeping track of indexes

后端 未结 15 2012
甜味超标
甜味超标 2020-11-22 10:01

Using C++, and hopefully the standard library, I want to sort a sequence of samples in ascending order, but I also want to remember the original indexes of the new samples.<

相关标签:
15条回答
  • 2020-11-22 10:24

    Suppose Given vector is

    A=[2,4,3]
    

    Create a new vector

    V=[0,1,2] // indicating positions
    

    Sort V and while sorting instead of comparing elements of V , compare corresponding elements of A

     //Assume A is a given vector with N elements
     vector<int> V(N);
     int x=0;
     std::iota(V.begin(),V.end(),x++); //Initializing
     sort( V.begin(),V.end(), [&](int i,int j){return A[i]<A[j];} );
    
    0 讨论(0)
  • 2020-11-22 10:26

    I wrote generic version of index sort.

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

    Usage is the same as that of std::sort except for an index container to receive sorted indexes. testing:

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

    you should get 2 1 0 3. for the compilers without c++0x support, replace the lamba expression as a class template:

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

    and rewrite std::sort as

    std::sort(pv.begin(), pv.end(), PairComp(comp)()) ;
    
    0 讨论(0)
  • 2020-11-22 10:28
    vector<pair<int,int> >a;
    
    for (i = 0 ;i < n ; i++) {
        // filling the original array
        cin >> k;
        a.push_back (make_pair (k,i)); // k = value, i = original index
    }
    
    sort (a.begin(),a.end());
    
    for (i = 0 ; i < n ; i++){
        cout << a[i].first << " " << a[i].second << "\n";
    }
    

    Now a contains both both our values and their respective indices in the sorted.

    a[i].first = value at i'th.

    a[i].second = idx in initial array.

    0 讨论(0)
提交回复
热议问题