基于另一个向量对点向量进行排序 我正在研究一个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)(假设Kstd::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
});
);
});