【问题标题】:c++ sort keeping track of indices [duplicate]c ++排序跟踪索引[重复]
【发布时间】:2012-05-21 19:10:16
【问题描述】:

您是否有一些有效的例程来返回数组,其中包含数组中已排序元素的索引?我认为使用 stl vector 存在一些方便的方法。您是否已经实现了没有 stl 的高效算法,或者您有参考伪代码或 C++ 代码?

【问题讨论】:

  • 所以你将一个包含索引的数组返回到另一个数组?这些索引将在您的新数组中以某种方式排序,它代表已排序但未实际排序的旧数组?

标签: c++ algorithm sorting stl


【解决方案1】:

添加到@Konrad 答案:

如果由于某种原因你不能使用 C++11,那么你可以使用boost::phoenix 来模拟它

    #include <vector>
    #include <algorithm>

    #include <boost/spirit/include/phoenix_core.hpp>
    #include <boost/spirit/include/phoenix_operator.hpp>

    template <typename T>
    std::vector<size_t> ordered(std::vector<T> const& values)
    {
        using namespace boost::phoenix;
        using namespace boost::phoenix::arg_names;

        std::vector<size_t> indices(values.size());
        int i = 0;
        std::transform(values.begin(), values.end(), indices.begin(), ref(i)++);
        std::sort(indices.begin(), indices.end(), ref(values)[arg1] < ref(values)[arg2]);
        return indices;
    }

【讨论】:

    【解决方案2】:

    你可以试试这样的:

    template<typename C>
    class index_sorter {
      public:
        compare(C const& c) : c(c) {}
        bool operator()(std::size_t const& lhs, std::size_t const& rhs) const {
          return c[lhs] < c[rhs];
        }
      private:
        C const& c;
    };
    
    std::sort(index_vector.begin(), index_vector.end(), index_sorter(vector));
    

    【讨论】:

      【解决方案3】:

      对于C++03,我觉得这个guru of the week可以帮助到你:

      namespace Solution3
      {
        template<class T>
        struct CompareDeref
        {
          bool operator()( const T& a, const T& b ) const
            { return *a < *b; }
        };
      
      
        template<class T, class U>
        struct Pair2nd
        {
          const U& operator()( const std::pair<T,U>& a ) const
            { return a.second; }
        };
      
      
        template<class IterIn, class IterOut>
        void sort_idxtbl( IterIn first, IterIn last, IterOut out )
        {
          std::multimap<IterIn, int, CompareDeref<IterIn> > v;
          for( int i=0; first != last; ++i, ++first )
            v.insert( std::make_pair( first, i ) );
          std::transform( v.begin(), v.end(), out,
                          Pair2nd<IterIn const,int>() );
        }
      }
      
      #include <iostream>
      
      int main()
      {
        int ai[10] = { 15,12,13,14,18,11,10,17,16,19 };
      
        std::cout << "#################" << std::endl;
        std::vector<int> aidxtbl( 10 );
      
      
        // use another namespace name to test a different solution
        Solution3::sort_idxtbl( ai, ai+10, aidxtbl.begin() );
      
      
        for( int i=0; i<10; ++i )
        std::cout << "i=" << i
                  << ", aidxtbl[i]=" << aidxtbl[i]
                  << ", ai[aidxtbl[i]]=" << ai[aidxtbl[i]]
                  << std::endl;
        std::cout << "#################" << std::endl;
      }
      

      原文是here

      【讨论】:

        【解决方案4】:

        使用 C++11,以下应该可以正常工作:

        template <typename T>
        std::vector<size_t> ordered(std::vector<T> const& values) {
            std::vector<size_t> indices(values.size());
            std::iota(begin(indices), end(indices), static_cast<size_t>(0));
        
            std::sort(
                begin(indices), end(indices),
                [&](size_t a, size_t b) { return values[a] < values[b]; }
            );
            return indices;
        }
        

        【讨论】:

        • 不应该是size_t 而不是unsigned
        • 在 C++11 中,您可以使用 std::iota 以增加值来填充向量。
        猜你喜欢
        • 2010-12-07
        • 2015-06-24
        • 1970-01-01
        • 2021-03-23
        • 2014-08-26
        相关资源
        最近更新 更多