Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/129.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何获取向量的那些元素,其中另一个向量有';1';s在相应的指数上_C++_Stl_Vector_Indices - Fatal编程技术网

C++ 如何获取向量的那些元素,其中另一个向量有';1';s在相应的指数上

C++ 如何获取向量的那些元素,其中另一个向量有';1';s在相应的指数上,c++,stl,vector,indices,C++,Stl,Vector,Indices,我有两个向量 std::vector<int> markedToBeRead(7); // contains: 1,1,0,0,1,0,1 std::vector<float> myVec(7); // contains: 1,2,3,4,5,6,7 谢谢大家! 像这样的 for (unsigned int i = 0; i < myVec.length(); i++) if (markedToBeRead[i] == 1)

我有两个向量

std::vector<int>   markedToBeRead(7);   // contains: 1,1,0,0,1,0,1
std::vector<float> myVec(7);            // contains: 1,2,3,4,5,6,7
谢谢大家!

像这样的

for (unsigned int i = 0; i < myVec.length(); i++)
    if (markedToBeRead[i] == 1)
        myResult.push_back(myVec[i]);
for(无符号整数i=0;i
显然,这里更倾向于使用简单的for循环,而不是任何STL算法

但是,作为一个概念的证明,我们可以在这里采用C++11中的stl::equals和lambda:

std::equal(myVec.begin(), myVec.end(), markedToBeRead.begin(), [&](float item, int mark)->bool {
    if (mark)
        myResult.push_back(item);
    return true;
});

这是可行的,但看起来很难看。

以下是我如何为此编写算法:

template <typename I, typename O, typename M>
void mask_copy(I begin, I end, O obegin, M mbegin) {
    for (; begin != end; ++begin, ++mbegin)
        if (*mbegin)
            *obegin++ = *begin;
}
模板
无效面具副本(我开始,我结束,O obegin,M mbegin){
for(;begin!=end;++begin,++mbegin)
如果(*mbegin)
*obegin++=*开始;
}
这样称呼:

int a[] = { 1, 2, 3, 4, 5, 6, 7, 8 , 9 };
bool m[] = { true, false, false, false, true, false, false, true, false };

std::vector<int> out;
mask_copy(begin(a), end(a), back_inserter(out), begin(m));
inta[]={1,2,3,4,5,6,7,8,9};
bool m[]={true,false,false,true,false,false,true,false};
std::向量输出;
屏蔽拷贝(开始(a)、结束(a)、反向插入器(输出)、开始(m));
(对于
std::begin
std::end
,需要C++11)


也就是说,库中的正确实现可能会使用
enable\u if
(或
static\u assert
)来确保所使用的迭代器类型与其使用兼容,即
i
是输入迭代器,
O
是兼容的输出迭代器,和
M
一个输入迭代器,其
value\u type
bool
。不幸的是,由于缺乏概念,这导致了真正的模板显示。

从功能上讲,这很简单:它是两个输入范围的压缩,后面是标记为1的过滤器,后面是仅提取值的映射

不幸的是,C++标准算法不太适合构图。如果您不介意创建中间容器,您可以应用二进制版本的
transform
,然后是
copy\u If
(或者C++03中的
remove\u copy\u If
,谓词颠倒,或者
remove\u If
来修改中间容器),然后是一元版本的
转换

或者,Boost以迭代器适配器的形式提供前两个操作。类似这样(未经测试):

struct标记{
bool运算符()(boost::tuple t){
返回t.get()==1;
}
};
auto first=boost::make_zip_迭代器(boost::make_元组(markedToBeRead.begin(),myVec.begin());
auto last=boost::make_zip_迭代器(boost::make_元组(markedToBeRead.end(),myVec.end());
std::transform(
boost::生成过滤器迭代器(第一个,最后一个),
boost::make_filter_迭代器(last,last),
std::反向插入器(myResults);
[](boost:tuple t){return t.get();}
);

你现在可能确信(a)循环更好,(b)用其他结构替换循环是C++中的一种旁观者运动;-< /P> 如果需要链接进一步的操作,则还可以用迭代器适配器替换

std::transform
transform\u迭代器

这对我很有用:

#include <algorithm>
#include <iostream>
#include <vector>

int main()  {
        std::vector<int>   markedToBeRead = {  1,1,0,0,1,0,1 };
        std::vector<float> myVec = { 1, 2, 3, 4, 5, 6, 7};

        // copy
        std::vector<float> result;
        std::copy_if(myVec.begin(), myVec.end(),
                std::back_inserter(result), [&](const float & f) {
                        return markedToBeRead[&f - &myVec[0]] == 1;
                });

        // Check result
        for (std::vector<float>::size_type i = 0; i < result.size(); ++i)
                std::cout << result[i] << " ";
}

#include

也可以发布您尝试过的任何内容。@potatosatter它们可能会以
myResult
结尾。您是被
向量所困扰,还是可以使用
valarray
替代?如果是这样,您可以使用
操作符[]的重载
返回一个
掩蔽数组
-这正是你在这里做的。谢谢你的快速回答!我尝试了这个,正如@Mohammad在他的回答中所建议的。但如果可能的话,我试图找到一种没有for循环的方法。我喜欢使用STL自己的方法。@Björn Pollex我不喜欢向量。好的,我将阅读some关于
masked_array
的帮助对于
val_array
@BjörnPollex和所有:如果
markedToBeRead
会显式包含索引呢?比如
markedToBeRead//contains:0,1,4,6
?简单明了。我认为任何使用标准算法的答案最终都不会那么清晰(尽管我通常主张使用算法而不是显式循环)。@Mohammad感谢你的建议。是的,我的问题精确到:-)。好的,我将继续使用这个作为循环建议。一个可能的优点是,它适用于任何序列,而不仅仅是
std::vector
,我(强烈反对)第一句。简单的算法总是优于循环,这只是更高层次的抽象。但由于没有简单的算法存在,这一点是没有意义的。@Konrad:奇怪,我同意你的说法(简单的算法优于循环,如果存在的话)和Gart的说法(循环优先于任何标准算法)。我看不出任何矛盾。正如你所指出的,没有标准算法是直截了当的。我认为关键是隐藏丑陋(无论是循环还是非直截了当的算法)在以标准算法风格设计的函数模板中。将其称为
select
或其他什么,并使用输出迭代器,而不是调用
push\u back
@Gart:我认为
std::equal
不能保证比较顺序,是吗?它在
输入迭代器上工作的事实当然,这很有启发性,但理论上它可以在迭代器类型上进行调度。我怀疑这是一种情况,尽管没有得到保证,但它实际上在任何地方都能工作。@Steve Jessop:当然,
std::equal
在这个例子中被滥用,我不知道OP是否真的需要一个强大的顺序保证。是的,理论上,它可能会给出所有相同的结果,但顺序错误,但在我看来,这几乎不可能,我之所以想这样做,是因为我知道它在Python中有多简单。经过15分钟的往返学习,了解boost迭代器适配器,然后想知道
auto
是否会简化代码,现在它就摆在我面前了。+1Inci
struct marked {
    bool operator()(boost::tuple<int, float> t) {
        return t.get<0>() == 1;
    }
};

auto first = boost::make_zip_iterator(boost::make_tuple(markedToBeRead.begin(), myVec.begin());
auto last = boost::make_zip_iterator(boost::make_tuple(markedToBeRead.end(), myVec.end());

std::transform(
    boost::make_filter_iterator<marked>(first, last),
    boost::make_filter_iterator<marked>(last, last),
    std::back_inserter(myResults);
    [](boost:tuple<int, float> t) { return t.get<1>(); }
);
#include <algorithm>
#include <iostream>
#include <vector>

int main()  {
        std::vector<int>   markedToBeRead = {  1,1,0,0,1,0,1 };
        std::vector<float> myVec = { 1, 2, 3, 4, 5, 6, 7};

        // copy
        std::vector<float> result;
        std::copy_if(myVec.begin(), myVec.end(),
                std::back_inserter(result), [&](const float & f) {
                        return markedToBeRead[&f - &myVec[0]] == 1;
                });

        // Check result
        for (std::vector<float>::size_type i = 0; i < result.size(); ++i)
                std::cout << result[i] << " ";
}