从 std::vector 中删除复制结构成员
remove copy struct member from std::vector
>我有一个结构成员的向量,如下所示:
struct pnt
{
bool has;
int num;
};
std::vector<pnt> myvector;
让我们有一个示例向量,如下所示:
myvector (num): 3 4 4 3 5 5 7 8 9 10 10
myvector (has): 1 1 0 1 0 1 0 0 0 1 0
我想做的是找到重复的成员(就具有相同的整数而言)并删除带有假布尔成员的成员。这样我的矢量就变成了这样:
myvector (num): 3 4 3 5 7 8 9 10
myvector (has): 1 1 1 1 0 0 0 1
为此,我编写以下函数:
void removeDuplicatedPnt(pnt_vec& myvector)
{
std::vector<pnt>::iterator pnt_iter;
for( pnt_iter = myvector.begin(); pnt_iter != myvector.end(); ++pnt_iter)
{
if(pnt_iter->has)
{
if(pnt_iter->num == (pnt_iter+1)->num)
{
myvector.erase(pnt_iter+1);
}
if(pnt_iter == myvector.begin())
{
continue;
}
if(pnt_iter->num == (pnt_iter-1)->num)
{
myvector.erase(pnt_iter-1);
pnt_iter++;
}
}
}
}
我也可以通过顺序检查成员来做到这一点。 但真正的向量可能很长。 所以这就是为什么我首先去寻找具有真布尔值的成员,然后我检查下一个和上一个成员。问题是我如何在效率和健壮性方面修改上面的代码。
注意:我只能使用 C++03(不能使用 C++11)。我也可以使用boos(1.53版),所以如果认为那里有任何有用的功能,请随意。:)
您可以使用
此算法:
- 收集
has
true
的所有num
set<int>
- 再次遍历
vector<pnt>
,并删除has
false
且num
存在于set<int>
中的所有条目
下面是一个示例实现:
struct filter {
set<int> seen;
bool operator()(const pnt& p) {
return !p.has && (seen.find(p.num) != seen.end());
}
};
...
filter f;
for (vector<pnt>::const_iterator i = v.begin() ; i != v.end() ; i++) {
if (i->has) {
f.seen.insert(i->num);
}
}
v.erase(remove_if(v.begin(), v.end(), f), v.end());
演示。
您可以将 std::sort 和 std::unique 与自定义比较谓词一起使用:
[](const pnt& a, const pnt& b) { return a.num < b.num; }
以下是使用增强范围来演示它的便捷方法,以减少打字:
更新 C++03 版本 Live On Coliru
#include <boost/range.hpp>
#include <boost/range/algorithm.hpp>
#include <iostream>
using namespace boost;
struct pnt {
int num;
bool has;
pnt(int num = 0, bool has = false) : num(num), has(has) {}
friend bool operator<(pnt const& a, pnt const& b) { return a.num<b.num; }
friend bool operator==(pnt const& a, pnt const& b) { return a.num==b.num; }
};
int main() {
std::vector<pnt> v { {10,0 },{10,1 },{9,0 },{8,0 },{7,0 },{5,1 },{5,0 },{3,1 },{4,0 },{4,1 },{3,1 } };
for (pnt p : boost::unique(boost::sort(v)))
std::cout << "{ num:" << p.num << ", has:" << p.has << "}n";
}
这实际上有一些更微妙的点,
可以例如it = std::find(v.begin(), v.end(), 3); // find a `pnt` with `num==3`
但这只是切线相关
相关文章:
- 在一个微不足道的可复制结构中,移动语义应该实现吗?
- 复制结构 tm
- 复制结构时,system.AccessVioLationException
- C++:是否隐式复制结构
- 复制结构的一部分
- 在不使用 std::copy 函数的情况下编写这个复杂的复制结构体
- memcpy 问题 -> 尝试复制结构数组
- 使用declard和参数转发构造函数隐式复制结构
- 如何复制结构数组
- 如何复制结构数组
- C++ 不带指针的复制结构
- 添加到矢量而不复制结构数据
- 从 std::vector 中删除复制结构成员
- 仅在发布版本中出错,从 std::vector 复制结构
- 引用或复制结构的结构(已分配的memset)是一件有效的事情
- 深度复制结构C++
- 如何从指向void的指针复制结构体
- 在新版本的 gcc 上返回隐式不可复制结构的 std::map 时出现编译错误
- C/C++是如何复制结构的
- c++内存复制结构体到字节数组中