Reputation: 77
I'm having trouble using my sort operator since I need to sort only the first element in the pair. The code is simple but is not working:
The operator is defined in:
struct sort_pred {
bool operator()(const CromosomaIndex &left, const CromosomaIndex &right) {
return left.first < right.first;
}
};
and the type is
typedef std::pair<double,int> CromosomaIndex;
I'm trying to sort the array like this:
CromosomaIndex nuevo[2];
nuevo[0].first = 0.01;
nuevo[0].second = 0;
nuevo[1].first = 0.009;
nuevo[1].second = 1;
int elements = sizeof(nuevo) / sizeof(nuevo[0]);
sort(nuevo, nuevo+ elements, sort_pred());
But the problem is that this is sorting the first and the second element and I only want to sort the first element and keep the second fixed. Any thoughts?
Upvotes: 2
Views: 431
Reputation: 208323
I am not sure that you understood the answer to the other question, but you do want the whole pair to be reordered according to the double
value. The original index (the int
) must be attached to the double
that was in that location in the original vector so that you can recover the location. Note that if you sorted only the double
within the pair
, then the value of the int
would be the location in the array... which does not need to be maintained as a datum at all.
Alternatively, you can consider a similar (although slightly different) solution. Create a single vector of integers that is initialized with values in the range [0..N)
where N
is the size of the vector of doubles. Then sort the vector of indices using a comparator functor that instead of looking at the value (int
) passed in will check the value in the original double
vector:
struct dereference_cmp {
std::vector<double> const & d_data;
dereference_cmp( std::vector<double> const & data ) : d_data(data) {}
bool operator()( int lhs, int rhs ) const {
return d_data[lhs] < d_data[rhs];
}
};
std::vector<double> d = ...;
std::vector<int> ints;
ints.reserve( d.size() );
for ( int i = 0; i < d.size(); ++i ) ints.push_back(i);
std::sort( d.begin(), d.end(), dereference_cmp(d) );
In this approach, note that what is not being reordered are the double
s, but rather the vector of indices. After the sort
completes the vector of indices will contain locations into the vector of double
such that i < j
=> d[ ints[i] ] <= d[ ints[j] ]
.
Note that in the whole process, what you want to reorder is the indices (in the original approach to be able to reconstruct the unsorted vector, in this approach to be able to find the values in sorted order), and the original vector is there only to provide the criterion for the sort.
Also note that the only reason to sort only the indices and not a modified container with both the value and the index would be if the cost of moving the data was high (say that each datum is a large object that cannot be cheaply moved, as a struct holding an array --not vector-- of data).
Upvotes: 1
Reputation: 726489
This approach sorts pairs as a single unit, which is what it is expected to do: it never make sense to break up the first
and the second
of the pair. If you would like to sort only the first
item and leave the second
in place, you will end up with a different set of pairs.
If you want to sort the first
separately from the second
, place them in separate arrays (better yet, use vector
s) and sort the first vector. Then iterate both vectors, and make a new set of pairs.
Upvotes: 2
Reputation: 283614
If you want the results to depend on the original order, use std::stable_sort
.
Upvotes: 5