我有一个名为mask的uchar数组。它包含0或1。
uchar mask
我有一个STL载体
vector<MyClass> vec
面具和vec的大小是相同的。
从vec形成子矢量的最佳方法是什么,其中包含掩码为1的地方的原始内容
答案 0 :(得分:1)
vector<MyClass> vec2;
vec2.resize(vec.size());
for (int i = 0; i < vec.size(); ++i) {
if (mask[i])
vec2[i] = vec[i];
}
尽可能简单。 vec2
将在面具为0
的位置包含类的默认构造对象,因此您需要某种方式将它们分开。
答案 1 :(得分:1)
一种简单的方法我喜欢“过滤掉”矢量的部分位置是readptr-writeptr成语:
int wp = 0;
for (int rp=0,n=v.size(); rp<n; rp++) {
if (<condition>) {
v[wp++] = v[rp];
}
}
v.resize(wp);
甚至使用:
if (wp != rp) v[wp] = v[rp];
wp++;
如果元素“重”并且没有检测到自我分配。
如果目的地是不同的向量,那么显式循环:
for (int rp=0,n=src.size(); rp<n; rp++) {
if (<condition>) {
dest.push_back(src[rp]);
}
}
在我看来,比使用copy_if
和back_inserter
内容更好(这也不能使索引可用于condition
部分)。
即使在C ++ 11中,您也可以使用lambda来使用
指定测试std::copy_if(src.begin(), src.end(),
[](const X& x) { return <condition>; },
std::back_inserter(dest));
这个基于<algorithm>
的代码更难以阅读(至少在我看来),而不是更短,编译时间更长,代码不会更好,编译器会生成三个无意义的bab呀声如果您在其中的任何位置输入拼写错误,则会显示错误消息。
使用C ++ 11版本
for (auto& x : src) if (condition) dst.push_back(x);
无论如何要好得多。
答案 2 :(得分:0)
如果您不想要mask为1的默认内容,那么它很简单:
vector<MyClass> sub;
for (size_t i = 0; i < mask.size(); ++i){
if (mask[i]) sub.push_back(vec[i]);
}
否则,如果编译器支持c ++ 0x,则可以使用transform with lambda。
vector<MyClass> sub;
std::transform(mask.begin(), mask.end(), vec.begin(), back_inserter(sub),
[](const uchar m, const MyClass &c){
return m ? c : MyClass();
});