Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/129.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
基于另一个向量对点向量进行排序 我正在研究一个C++应用程序。_C++_Sorting_C++11_Vector_Stl Algorithm - Fatal编程技术网

基于另一个向量对点向量进行排序 我正在研究一个C++应用程序。

基于另一个向量对点向量进行排序 我正在研究一个C++应用程序。,c++,sorting,c++11,vector,stl-algorithm,C++,Sorting,C++11,Vector,Stl Algorithm,我有两个点向量 vector<Point2f> vectorAll; vector<Point2f> vectorSpecial; 我可以进行双循环并保存索引。然后根据点的索引对点进行排序。然而,当我们有很多点时,这种方法花费的时间太长(例如,vectorAll中有10000点,vectorSpecial中有1000点,这是一千万次迭代) 有什么更好的方法可以做到这一点 第二步: vectorSpecial中的某些点在vectorAll中可能不可用。我需要取离它最近

我有两个点向量

vector<Point2f> vectorAll;
vector<Point2f> vectorSpecial;  
我可以进行双循环并保存索引。然后根据点的索引对点进行排序。然而,当我们有很多点时,这种方法花费的时间太长(例如,vectorAll中有10000点,vectorSpecial中有1000点,这是一千万次迭代)

有什么更好的方法可以做到这一点

第二步:

vectorSpecial中的某些点在vectorAll中可能不可用。我需要取离它最近的点(使用通常的距离公式
sqrt((x1-x2)^2+(y1-y2)^2)

循环时也可以这样做,但如果有人对更好的方法有任何建议,我将不胜感激


非常感谢您的帮助

您可以使用
vectorAll
上的
std::sort
Compare
功能,该功能旨在考虑
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);
struct mycomparstruct
{
std::矢量all;
std::特殊载体;
myComparstruct(常数std::vector&a,常数std::vector&s)
:全部(a)、特殊(s)
{
}
布尔运算符()(常数点2F&i,常数点2F&j)
{ 
//不管逻辑是什么
}
};
std::矢量all;
std::特殊载体;
//填充向量
MyComparstruct compareObject(全部、特殊);
std::sort(special.begin()、special.end()、compareObject);

对于您的第一步,您可以使用C++11 lambda来获得巨大的效果(special.size()=K,all.size()=N)

解释:与第一步相比,唯一的变化是,对于
特殊
中的每个元素,您可以在
所有
中找到最接近它的元素,您可以按照问题中的建议计算最小欧几里德距离


更新:您可以先将
all
的每个元素的索引存储到
std::unordered_映射
哈希表中,然后在查找到该哈希表的基础上对
special
的元素进行比较,从而进行空间/时间权衡。这将第一步的时间复杂度降低到O(N)(假设K这似乎是我需要的。但有两件事:1)在算符函数中,它取2个点作为输入,我比较它们的x和y?2) 我需要对“特殊”向量而不是“全部”进行排序,因此我需要通过调用
std::sort(special.begin()、special.end()、compareObject)对其进行排序?我在C++方面经验不太丰富,谢谢answering@Youssef好啊然后你的操作符应该取2个点作为参数,而不是int,这只是一个例子。关于第二个问题,是的,我以为你想把所有的都分类。将进行编辑。@LuchianGrigore,运算符的输入可以是不同的类型吗?那么点2f和点3f?逻辑和其他输入是否匹配?是的,但不能有不同类型的容器。请注意,调用STL算法并不能消除循环,它只是将它们隐藏在抽象层后面。
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);
#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];
});
// 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    
         });
     ); 
});