C++ sortowanie indeksów

Czy masz jakąś sprawną procedurę zwracania tablicy z indeksami dla posortowanych elementów w tablicy? Myślę, że istnieje jakiś wygodny sposób użycia stl vector. Czy zaimplementowałeś już wydajne algo bez stl, czy masz ref do pseudo kodu lub kodu C++?

Dzięki i pozdrawiam

Author: octoback, 2012-05-14

4 answers

Używanie C++11 powinno działać poprawnie:

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;
}
 34
Author: Konrad Rudolph,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-05-14 09:55:09

Możesz spróbować czegoś takiego:

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));
 7
Author: Pubby,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-05-14 10:04:10

Dodaję do @Konrad odpowiedź:

Jeśli z jakiegoś powodu nie jesteś w stanie używać C++11, możesz użyć boost::phoenix, aby symulować go tak, jak

    #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;
    }
 4
Author: Kostya,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-05-14 14:45:35

Dla C++03, myślę, że ten guru tygodnia może Ci pomóc:

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

Oryginalny artykuł jest Tutaj .

 2
Author: Alessandro Teruzzi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-05-14 09:58:26