How to sort a multidimensional vector of floats?

2019-02-28 16:32发布

问题:

So, I have a set of points in 3D, and I would like to store them in a 3 dimensional vector. Then I need sort that vector, giving priority first to the X dimention, then Y, then Z. So, for example, if I have this set of points:

P1 = (5, 10 ,9)
P2 = (1, 11, 4)
P3 = (8, 5, 2)
P4 = (5, 10, 3)
P5 = (5, 4, 0)

I would like to get a vector sorted like this:

[1, 11, 4]
[5, 4, 0]
[5, 10, 3]
[5, 10, 9]
[8, 5, 2]

So, how can a sort a multidimentional vector taking all rows into account? Should I use std::priority_queue instead? If so, how show I use it?

Thanks

回答1:

...giving priority first to the X dimention, then Y, then Z

Use std::sort with std::tie, something like following

#include <algorithm>
#include <tuple>
//....

struct Points // Your 3D Point
{
    float x,y,z;
} ;

std::vector<Points> v; // Vector of 3D points

std::sort( v.begin(), v.end(), 
            []( const Points& lhs, const Points& rhs )
            {
                return std::tie(lhs.x,lhs.y,lhs.z) 
                     < std::tie(rhs.x,rhs.y,rhs.z)  ; 

            }
         ) ;

DEMO



回答2:

You could use an std::tuple<double, double, double> to represent a point. The comparison for std::tuple works lexicographically, the way you want it to. Alternatively, you could provide a custom sort function to your vector of points. Something like this:

sort(pointVector.begin(), pointVector.end(), [](const Point& lhs, const Point& rhs){//Implement your required comparison predicate here});

Also, as this question shows, you can achieve some sort of a named-tuple-with-lexicographic-sorting by using std::tuples lexicographic sort and std::tie.



回答3:

You can use the std::sort() to easily sort according to your specific conditions by making your own comparator function.

Assuming you have stored a single 3D point in a struct point, and the points in a std::vector<points> (A std::tuple might be more useful.), try out this code.

Example:

#include <vector>
#include <algorithm>
using namespace std;
struct point
{
     float x, y, z;
}
bool mySort(const point& a, const point& b)
{
    //A naive comparison to help you understand better.
    //You could always use std::tie for lexicographical comparison.
    if (a.x == b.x)
    {
        if (a.y == b.y)
            return a.z < b.z;
        else
            return a.y < b.y;
    }
    else
        return a.x < b.x;
}
int main()
{
    vector<point> graph;
    //push_back() all your points into the graph.
    //mySort() is a custom comparator function.
    sort(graph.begin(),graph.end(),mySort); 
}