boost zip_iterator and std::sort

前端 未结 4 1890
北荒
北荒 2020-11-29 10:14

I have two arrays values and keys both of the same length. I want to sort-by-key the values array using the keys array a

4条回答
  •  广开言路
    2020-11-29 11:07

    A very good discussion of this problem can be found here: https://web.archive.org/web/20120422174751/http://www.stanford.edu/~dgleich/notebook/2006/03/sorting_two_arrays_simultaneou.html

    Here's a possible duplicate of this question: Sorting zipped (locked) containers in C++ using boost or the STL

    The approach in the link above uses std::sort, and no extra space. It doesn't employ boost::zip_iterator, just boost tuples and the boost iterator facade. Std::tuples should also work if you have an up to date compiler.

    If you are happy to have one extra vector (of size_t elements), then the following approach will work in ~ o(n log n) time average case. It's fairly simple, but there will be better approaches out there if you search for them.

    #include 
    #include 
    #include 
    #include 
    
    using namespace std;
    
    template 
    void sortByPerm(vector& list1, vector& list2) {
      const auto len = list1.size();
      if (!len || len != list2.size()) throw;
    
      // create permutation vector
      vector perms;
      for (size_t i = 0; i < len; i++) perms.push_back(i);
      sort(perms.begin(), perms.end(), [&](T1 a, T1 b){ return list1[a] < list1[b]; });
    
      // order input vectors by permutation
      for (size_t i = 0; i < len - 1; i++) {
        swap(list1[i], list1[perms[i]]);
        swap(list2[i], list2[perms[i]]);
    
        // adjust permutation vector if required
        if (i < perms[i]) {
          auto d = distance(perms.begin(), find(perms.begin() + i, perms.end(), i));
          swap(perms[i], perms[d]);
        }
      }
    }
    
    int main() {
      vector ints = {32, 12, 40, 8, 9, 15};
      vector doubles = {55.1, 33.3, 66.1, 11.1, 22.1, 44.1};
    
      sortByPerm(ints, doubles);   
    
      copy(ints.begin(), ints.end(), ostream_iterator(cout, " ")); cout << endl;
      copy(doubles.begin(), doubles.end(), ostream_iterator(cout, " ")); cout << endl;
    }
    

提交回复
热议问题