使用uchar数组屏蔽C ++向量

时间:2014-10-24 06:12:58

标签: c++ stl

我有一个名为mask的uchar数组。它包含0或1。

uchar mask

我有一个STL载体

vector<MyClass> vec

面具和vec的大小是相同的。

从vec形成子矢量的最佳方法是什么,其中包含掩码为1的地方的原始内容

3 个答案:

答案 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_ifback_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();
});