order a vector of points based on another vector

眉间皱痕 提交于 2019-12-04 03:11:49

问题


I am working on a C++ application.

I have 2 vectors of points

vector<Point2f> vectorAll;
vector<Point2f> vectorSpecial;  

Point2f is defined typedef Point_<float> Point2f;

vectorAll has 1000 point while vectorSpecial has 10 points.

First Step:

I need to order the points in vectorSpecial depending on their order in vectorAll. So something like this:

For each Point in vectorSpecial
    Get The Order Of that point in the vectorAll
    Insert it in the correct order in a new vector

I can do a double loop and save the indexes. and then order the points based on their indexes. However this method is taking too long when we have lots of points (for example 10000 points in vectorAll and 1000 points in vectorSpecial so that's ten million iteration)

What are better methods of doing that?

Second Step:

Some points in vectorSpecial might not be available in vectorAll. I need to take the point that is closest to it (by using the usual distance formula sqrt((x1-x2)^2 + (y1-y2)^2))

This also can be done when looping, but if someone has any suggestions for better methods, I would appreciate it.

Thanks a lot for any help


回答1:


You can use std::sort on vectorAll with the Compare function designed to take into account the contents of vectorSpecial:

struct myCompareStruct
{
    std::vector<Point2f> all;
    std::vector<Point2f> special;
    myCompareStruct(const std::vector<Point2f>& a, const std::vector<Point2f>& s)
        : all(a), special(s) 
    {
    }
    bool operator() (const Point2f& i, const Point2f& j) 
    { 
        //whatever the logic is
    }
};

std::vector<Point2f> all;
std::vector<Point2f> special;
//fill your vectors
myCompareStruct compareObject(all,special);

std::sort(special.begin(),special.end(),compareObject);



回答2:


For your First Step, you can use C++11 lambda's to great effect (special.size() = K, and all.size() = N)

#include <algorithm>   // std::sort, std::transform, std::find, std::min_element
#include <iterator>    // std::distance

std::vector<int> indices;
indices.reserve(special.size());

// locate exact index in all for every element of special. Complexity = O(K * N)
std::transform(special.begin(), special.end(), indices.begin(), [&all](Point2f const& s){                   
     return std::distance(
         all.begin(), 
         std::find(all.begin(), all.end(), s)
     ); 
});

// sort special based on index comparison. Complexity = O(K * log(K))
std::sort(special.begin(), special.end(), [&indices](Point2f const& r, Point2f const& s){
     auto i = std::distance(special.begin(), r);
     auto j = std::distance(special.begin(), s);
     return indices[i] < indices[j];
});

Explanation: first, for every point in special, compute the distance between the beginning of all and the location of the special element in all, and store that result into the indices vector. Second, sort all elements of special by comparing for every pair of element the corresponding elements in the indices vector.

For your Second Step, you only have to change the way you compute indices

// locate closest element in all for every element of special. Complexity = O(K * N)
std::transform(special.begin(), special.end(), indices.begin(), [&all](Point2f const& s){                   
     return std::distance(
         all.begin(), 
         std::min_element(all.begin(), all.end(), [&s](Point2f const& a){
              return // Euclidean 2D-distance between a and s    
         });
     ); 
});

Explanation: the only change compared to your First Step is that for every element in special you find the element in all that is closest to it, which you do by computing the minimum Euclidean distance as you suggested in your question.

UPDATE: You could make a space/time tradeoff by first storing the index of every element of all into a std::unordered_map hash table, and then doing the comparison between elements of special based on lookup into that hash table. This reduces the time complexity of the first step to O(N) (assuming K < N), but adds O(N) of storage for the hash table.



来源:https://stackoverflow.com/questions/11341498/order-a-vector-of-points-based-on-another-vector

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!