I have a point structure:

struct Point { double x; double y; }; 

I have two arrays of these points, one of which ( ans ) needs to be sorted first by X, then by the game:

  Point p[51],ans[400000]; 

By analogy with the example, which I found here for the integer values ​​of the structure, I tried to write for my case:

 sort(ans,ans+sochcnt+1, [&](Point &a, Point &b){ return RealLessEq(ax,bx) }); sort(ans,ans+sochcnt+1, [&](Point &a, Point &b){ return RealLessEq(ay,by) }); 

where RealLessEq is the procedure for comparing two real numbers (returns true if a<=b ):

 bool RealLessEq(double a, double b) { if ((ab)<=Eps) { return 1; } else { return 0; } } 

where double Eps=1e-6;
Compiler for sort(ans,ans+sochcnt+1, [&](Point &a, Point &b){ return RealLessEq(ax,bx) }); gives the expected ';' before '}' token| error expected ';' before '}' token| expected ';' before '}' token|

Tell me how to do it correctly.

  • one
    What does it mean "sort by X first, then by game:"? That is, after the first sorting, the second sorting is performed, which completely crosses out the first sorting? - Vlad from Moscow

2 answers 2

Well, they answered you quite understandably - you forgot the semicolon:

 sort(ans,ans+sochcnt+1, [&](Point &a, Point &b){ return RealLessEq(ax,bx); }); ^ 

But there are more comments. I do not even know where to start ...
Sort first by X, then by the game - how's that? Just sort by x , work, and then again - by y , losing sorting by x ? Or should x be sorted by y ? You solve the problem in the first understanding, but not in the second! To solve in the second variant, there must be a function that compares x , and when equal , y . About

 [](const Point&a, const Point&b) { return (ax < bx) ? true : (ax > bx) ? false : (ay < by); } 

Further, if you have sochcnt elements in the array, then the sorting should be called as

 sort(ans,ans+sochcnt, ... 

Of course, if their sochcnt+1 , then you have everything right, then I just do not know.

And yet - the comparator returns a comparison result less , not less or equal . Strictly less. If he needs a test for equality, the algorithm will execute it himself, like !((a<b)||(b<a)) .

    In both these sentences

     sort(ans,ans+sochcnt+1, [&](Point &a, Point &b){ return RealLessEq(ax,bx) }); ^^ sort(ans,ans+sochcnt+1, [&](Point &a, Point &b){ return RealLessEq(ay,by) }); ^^ 

    you inside the body of lambda expressions forgot to specify a semicolon.

    This function is incorrect.

     bool RealLessEq(double a, double b) { if ((ab)<=Eps) { return 1; } else { return 0; } } 

    since the comparison must satisfy the condition (the so-called strict weak ordering ), in which, for example, the expression! RealLessEq (x, x) must be true . That is, should have a check for strict inequality.

    Therefore, at least this function, if it is used in sorting, should be written as

     bool RealLessEq(double a, double b) { return a < b; } 

    To get pointers to the beginning of the array and to the end of the array, that is, to the place after the last element of the array, you can use the standard functions std::begin and std::end , which are enclosed in the <iterator> header, to specify a range of iterators.

    The call of standard algorithm will look as follows

     std::sort(std::begin(ans), std::end(ans), [](const Point &a, const Point &b) { return RealLessEq(ax, bx); }); 

    or for sorting by second coordinates

     std::sort(std::begin(ans), std::end(ans), [](const Point &a, const Point &b) { return RealLessEq(ay, by); }); 

    Here is a demo program.

     #include <iostream> #include <algorithm> #include <iterator> bool RealLessEq(double a, double b) { return a < b; } int main() { struct Point { double x; double y; }; Point ans[] = { { 2, 3 }, { 1, 4 }, { 3, 0 } }; std::sort(std::begin(ans), std::end(ans), [](const Point &a, const Point &b) { return RealLessEq(ax, bx); }); for (const auto &p : ans) { std::cout << px << ' ' << py << std::endl; } std::cout << std::endl; std::sort(std::begin(ans), std::end(ans), [](const Point &a, const Point &b) { return RealLessEq(ay, by); }); for (const auto &p : ans) { std::cout << px << ' ' << py << std::endl; } return 0; } 

    Its output to the console

     1 4 2 3 3 0 3 0 2 3 1 4 

    In principle, the RealLessEq function is not RealLessEq for such a simple comparison of floating-point numbers. You could write a lambda expression, for example, in the form

      std::sort(std::begin(ans), std::end(ans), [](const Point &a, const Point &b) { return ax < bx; }); 

    If you need to sort the points by x , and then inside this sort by y , this is done simply using the standard function std::tie , declared in the <tuple> header. For example,

     std::sort(std::begin(ans), std::end(ans), [](const Point &a, const Point &b) { return std::tie( ax, ay ) < std::tie( bx, by ); });