如何根据`std :: set`

时间:2016-02-23 23:07:48

标签: c++

有没有一种方法可以根据std::vector中的元素对std::set进行切片?换句话说,std::set中的元素在向量中保存了我想要的索引。当然,我可以用代码完成这个:

#include <set>
#include <vector>
#include <iostream>
#include <iterator>

template <typename T>
std::vector <T> slice(
    std::vector <T> const & x,
    std::set <unsigned int> const & I
) {
    auto y = std::vector <T> ();
    for(auto const & i : I)
        y.push_back(x[i]);
    return y;
}

int main() {
    auto x = std::vector <double> { 1.2, 2.3, 3.4, 4.5, 5.6};
    auto I = std::set <unsigned int> { 0, 3, 4};
    auto y = slice(x,I);
    std::copy(y.begin(),y.end(),std::ostream_iterator <double>(
        std::cout,"\n"));
}

正确返回

1.2
4.5
5.6

然而,这感觉有点笨拙。还有更好的方法吗?

3 个答案:

答案 0 :(得分:5)

只需使用std::transform

即可实现此目的
int main()
{
  std::vector<double> x { 1.2, 2.3, 3.4, 4.5, 5.6};
  std::set<unsigned int> I { 0, 3, 4};
  std::vector<double> y(I.size());

  std::transform(I.begin(), I.end(), y.begin(),
    [&x](unsigned int i) { return x[i]; });

  std::copy(y.begin(),y.end(),std::ostream_iterator <double>(std::cout,"\n"));  
}

答案 1 :(得分:4)

您还可以使用std::transformstd::back_inserter

template <typename T>
std::vector <T> slice(
    std::vector<T> const &x,
    std::set<unsigned int> const &I) 
{
    std::vector<double> result;
    std::transform(I.begin(), I.end(), std::back_inserter(result),
        [&x](unsigned int i) { return x[i]; });
    return result;
}

答案 2 :(得分:2)

template <typename T>
std::vector <T> slice2(
    std::vector <T> const & x,
    std::set <unsigned int> const & I
    )
{
    auto z = std::vector <double>();
    std::for_each(I.begin(), I.end(), [&](const unsigned int &i)
    {
        z.push_back(x[i]);
    });
    return z;
}