我是C ++的新手,想要消除矢量元素。
我的载体就像:
<vector<vector>> objPoints;
<vector<vector>> delPoints;
<vector<vector>> objPoints2;
每个objPoints的大小为1000x3并且具有所有点数。从objPoints我想删除delPoints,即每行中的(X,Y,Z)值。
有人可以告诉我语法吗?
答案 0 :(得分:2)
我将您的问题解释如下:您有两个向量objPoints
和delPoints
,其中包含1000个三维点。我会把它编码为
std::vector<std::array<int,3> > objPoints;
我认为你有一些光栅,你可以用int
值来表示你的分数(否则,对于double
条目,比较并不那么容易。)
使用std::array<int,3>
的一个好处是,您可以自动获得点的词典排序(即std::less
和std::equal_to
的特化,可直接使用而无需进一步使用创造一些)。
<强>算法:强>
首先对数组进行排序。可能有一些算法并不是必需的(请参阅@AshwaniDausodia的其他答案),但以下假定它。此外,通常通过使用排序的向量,可以获得更好的性能(至少在大O中:对于未排序的容器,它大致为O(size1*size2)
,而对于以下算法则较低)。排序首先需要努力O(size1 log(size1)) + O(size2 log(size2))
接下来,同时遍历两个数组,每次找到一个公共元素时,都会从其中一个向量中删除它。当您遍历排序数组时,您始终只能增加指向较小元素的迭代器,此步骤需要O(size1+size2)
。
<强>实施强>
// deletes the elements from container c1 which are also present in c2
// requires sorted containers c1 and c2
//
template< class ContainerType1, class ContainerType2 >
void delete_common_elements(ContainerType1& c1, ContainerType2 const& c2 )
{
for(auto it1=c1.begin(), it2=c2.begin()
; it1!=c1.end() && it2!=c2.end(); )
{
if(*it1==*it2) // eventually change here if your points are not int's
// but are of floating-point type
{
it1 = c1.erase(it1); //it1 is increased here
}
else
{
*it1<*it2 ? ++it1 : ++it2;
}
}
}
总之,这需要O(c1.size()) + O(c1.size() * log(c1.size())
的努力(自然地假设为c1.size()>=c2.size()
)。
可以很容易地扩展它以采用任意比较运算符而不是operator==
。
答案 1 :(得分:0)
如果你肯定必须使用向量,一种简单(但效率低)的方法是std::find
要删除的obj要素中的元素,然后用std::vector::erase
将其删除。
答案 2 :(得分:0)
一种不同的方法是:
for each point in delPoints
if point exists in objPoints
delete point from objPoints.
如果允许您对矢量进行排序,则可以更有效地执行此操作。我将为您提供方法和伪代码,然后您可以自己实现它。
First sort objPoints and delpoints
i=0,j=0
while i < length(objPoints) and j < length(delPoints)
if objPoints[i] > delPoints[j] // Means delPoints[j] is not there in objPoints. If it would have, we would have found it.
j++
else if objPoints[i] < delPoints[j] // Means delPoints[j] is after objPoints[i] if it is there in objPoints
i++
else
erase objPoints[i] // Means we have found delPoints[j], so delete it.
对于comaprison,首先比较w.r.t x cordinate
然后y
然后z
。对于排序,您可以使用std::sort
与前一行中描述的相同比较功能。要删除,您可以使用std::vector::erase
或者你可以实现自己的功能。
答案 3 :(得分:0)
您可以考虑阅读this Q&A on StackOverflow on how to erase elements from STL containers。
关键是使用 erase-remove idiom 来清除向量中的项目,并使用lambda来表示擦除条件:
objPoints.erase(
std::remove_if(
objPoints.begin(),
objPoints.end(),
[&delPoints](const Point3D& point)
{
// Erasing condition:
// Is 'point' contained in the 'delPoints' vector?
auto it = std::find(delPoints.begin(), delPoints.end(), point);
return (it != delPoints.end());
}),
objPoints.end());
完整的可编辑代码示例(live here):
#include <algorithm> // for std::find(), std::remove_if()
#include <array> // for std::array
#include <iostream> // for console output
#include <vector> // for std::vector
typedef std::array<int, 3> Point3D;
std::ostream& operator<<(std::ostream& os, const Point3D& point)
{
os << "{" << point[0] << ", "
<< point[1] << ", " << point[2] << "}";
return os;
}
std::ostream& operator<<(std::ostream& os, const std::vector<Point3D>& v)
{
if (v.empty())
{
os << "{ <empty> }" << std::endl;
return os;
}
os << "{\n";
for (const auto& point : v)
{
os << " " << point << '\n';
}
os << "}" << std::endl;
return os;
}
int main()
{
std::vector<Point3D> objPoints{{1, 2, 3},
{4, 5, 6},
{11, 22, 33},
{44, 55, 66},
{77, 88, 99}};
std::vector<Point3D> delPoints{{10, 10, 10},
{11, 22, 33},
{44, 55, 66}};
std::cout << "objPoints =\n" << objPoints << std::endl;
std::cout << "delPoints =\n" << delPoints << std::endl;
objPoints.erase(
std::remove_if(
objPoints.begin(),
objPoints.end(),
[&delPoints](const Point3D& point)
{
// Erasing condition:
// Is 'point' contained in the 'delPoints' vector?
auto it = std::find(delPoints.begin(), delPoints.end(), point);
return (it != delPoints.end());
}),
objPoints.end());
std::cout << "\nAfter erasing, objPoints =\n";
std::cout << objPoints << std::endl;
}
输出:
objPoints = { {1, 2, 3} {4, 5, 6} {11, 22, 33} {44, 55, 66} {77, 88, 99} } delPoints = { {10, 10, 10} {11, 22, 33} {44, 55, 66} } After erasing, objPoints = { {1, 2, 3} {4, 5, 6} {77, 88, 99} }