C++ sorting and keeping track of indexes

后端 未结 15 2175
甜味超标
甜味超标 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:09

    I came across this question, and figured out sorting the iterators directly would be a way to sort the values and keep track of indices; There is no need to define an extra container of pairs of ( value, index ) which is helpful when the values are large objects; The iterators provides the access to both the value and the index:

    /*
     * a function object that allows to compare
     * the iterators by the value they point to
     */
    template < class RAIter, class Compare >
    class IterSortComp
    {
        public:
            IterSortComp ( Compare comp ): m_comp ( comp ) { }
            inline bool operator( ) ( const RAIter & i, const RAIter & j ) const
            {
                return m_comp ( * i, * j );
            }
        private:
            const Compare m_comp;
    };
    
    template 
    void itersort ( INIter first, INIter last, std::vector < RAIter > & idx, Compare comp )
    { 
        idx.resize ( std::distance ( first, last ) );
        for ( typename std::vector < RAIter >::iterator j = idx.begin( ); first != last; ++ j, ++ first )
            * j = first;
    
        std::sort ( idx.begin( ), idx.end( ), IterSortComp< RAIter, Compare > ( comp ) );
    }
    

    as for the usage example:

    std::vector < int > A ( n );
    
    // populate A with some random values
    std::generate ( A.begin( ), A.end( ), rand );
    
    std::vector < std::vector < int >::const_iterator > idx;
    itersort ( A.begin( ), A.end( ), idx, std::less < int > ( ) );
    

    now, for example, the 5th smallest element in the sorted vector would have value **idx[ 5 ] and its index in the original vector would be distance( A.begin( ), *idx[ 5 ] ) or simply *idx[ 5 ] - A.begin( ).

提交回复
热议问题