Using std::sort in unusual way

Is it possible to sort vector this way?
How can i obtain that result?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
double cmp(Point* p1, Point* p2) {
    return p2->getX()*p1->getY()-p1->getX()*p2->getY();
}


int main() {
    vector<Point*> pts;
    sort(pts.begin()+1, pts.end(), cmp);
    return 0;
}

//pts[0] stays in place as it is
//other ones are sorted by cmp(Point* p1, Point* p2) comparator like this
//cmp(pts[0], pts[1])...
//cmp(pts[0], pts[2])...
//cmp(pts[0], pts[3])...
//cmp(pts[0], pts[4])... 
Go ahead and make cmp a boolean and cast your answer to that. Its cleaner.
as far as I know as long as your function returns something that can be converted to bool and takes 2 args, its legal. What you get out may not make much sense, but it should work.

be aware that std::sort is NOT bubble sort and MAY NOT compare every item against every other item in any way you can make sense of. It specifically is coded to NOT do that so it will run faster...

if you need it sorted in some wonky way, proceed. If you are trying to use sort to do something else, try again.
Last edited on
The cmp function needs to return a bool, something like:

1
2
3
bool cmp(const Point* p1, const Point* p2) {
    return p2->getX() * p1->getY() < p1->getX() * p2->getY();
}

Also, I don't understand how you are wanting to sort it.
You seem to want to compare everything to pts[0].
Give a small example of an input vector and the expected output.
1
2
3
4
5
6
7
8
9
10
vector<Point*> points;
vector<double> sorted;

Point* minimPoint = points[0];
points.erase(points.begin());
NoPoints--;

for(int i = 0; i < NoPoints; i++) {
      sorted.push_back(cmp(minimPoint, points[i]));
}

so now i get generated by cmp values in vector<double>
is there any option to sort vector of points using vector sorted?
i mean to associate something like this
points[0] = blah blah assoc with sorted[0] = 42.12
points[1] = blah blah assoc with sorted[1] = -53.12
points[2] = blah blah assoc with sorted[2] = 21.53
...
and then sort the points vector based on sorting double values in second vector? to make it something like this
sorted points output:
points[0] = blah blah, sorted[0] = -10.24
points[1] = blah blah, sorted[1] = -8.15
points[2] = blah blah, sorted[2] = 5.24
points[3] = blah blah, sorted[3] = 6.2
is there any option to sort vector of points using vector sorted?
that would get ugly. you can make cmp access a global variable type thing (there are ways to globalize data that isnt a pure nasty global variable) and use that vector instead of what was passed in to make the decision. But what in the heck are you actually doing here? If feels like your problem is not well defined, and you are chasing down a rabbit hole that will lead nowhere good.

it feels like whatever you want to do could be done in that for loop.
let me make some assumptions here... you want points to be sorted by whether each point is bigger or smaller than min point thing?
if so, do it in the loop.
make a vector sized nopoints.
grab the back end (nopoints -1):
int backend = nopoints-1; //literally this
and the front:
int frontend = 0;
good times. now this:
bool cmpresult;
1
2
3
4
5
6
7
8
for(int i = 0; i < NoPoints; i++) 
{
    cmpresult = cmp(minimPoint, points[i]);
    if(cmpresult)
      newvec[frontend++] = points[i];
      else
      newvec[backend--] = points[i];
}

and bam, its sorted as you asked. Or at least that is the idea, I didn't test this.
*** odds are it would perform better if newvec were a vector of integers and it held 'i' instead of points. Then you could refer back to i in the real array for the point data, instead of all that copying of the data. If that works for your application.

you can also do as you were doing, sort the points array with a function that does what you need, then find the entry where it goes from < min to > min and split it. Since it is sorted, you just find the break in other words? That may also be what you were asking.
Last edited on
Is it possible to sort vector this way?
std::sort requires that its comparator implements a strict weak order.

Seems more likely that you want to partition the vector about a particular point:
1
2
3
4
5
if (xs.size()) 
  std::partition(xs.begin(), xs.end(), [pivot=*xs[0]](auto elt)
    { 
      return *elt < pivot;
    });

But I don't understand what's going on in your example.

Topic archived. No new replies allowed.