过滤器标准::向量 标准::字符串的

Filter std::vector of std::string's

本文关键字:标准 字符串 向量 过滤器      更新时间:2023-10-16

如何生成一个输出向量,该向量根据输入向量是否以某个子字符串开头来过滤输入向量。我正在使用 c++98 和提升。

据我所知:

std::string stringToFilterBy("2");
std::vector<std::string> input = boost::assign::list_of("1")("2")("22")("33")("222");
std::vector<int> output;
boost::copy( input | boost::adaptors::filtered(boost::starts_with), std::back_inserter(output) );

你可以改用 std::remove_copy_if:

#include <algorithm>
#include <iterator>
#include <vector>
struct filter : public std::unary_function<std::string, bool> {
    filter(const std::string &by) : by_(by) {}
    bool operator()(const std::string &s) const {
        return s.find(by_) == 0;
    }
    std::string by_;
};
std::vector<std::string> in, out;
std::remove_copy_if(in.begin(), in.end(), std::back_inserter(out),
                    std::not1(filter("2")));

一种方法是:

#include <boost/algorithm/string/predicate.hpp>
#include <boost/range/algorithm/copy.hpp>
#include <boost/range/adaptor/filtered.hpp>
#include <boost/range/adaptor/transformed.hpp>
#include <boost/assign.hpp>
#include <boost/bind.hpp>
#include <boost/lexical_cast.hpp>
#include <string>
#include <iterator>
#include <vector>
int main() {
    std::string stringToFilterBy("2");
    std::vector<std::string> input =
        boost::assign::list_of("1")("2")("22")("33")("222");
    std::vector<int> output;
    boost::copy(
        input
      | boost::adaptors::filtered(
            boost::bind(
                boost::starts_with<std::string,std::string>, _1, stringToFilterBy))
      | boost::adaptors::transformed(boost::lexical_cast<int, std::string>),
        std::back_inserter(output));
}

或者没有boost::bind(这种方式避免了命名类型,避免了对函数指针的需求,但需要添加一些一次性结构):

#include <boost/algorithm/string/predicate.hpp>
#include <boost/range/algorithm/copy.hpp>
#include <boost/range/adaptor/filtered.hpp>
#include <boost/range/adaptor/transformed.hpp>
#include <boost/assign.hpp>
#include <boost/lexical_cast.hpp>
#include <string>
#include <iterator>
#include <vector>
template<typename Range1T>
struct StartsWith_T {
    StartsWith_T(Range1T const& test) : test(&test) {}
    template<typename Range2T>
    bool operator()(Range2T const& input) const {
        return boost::starts_with(input, *test);
    }
    Range1T const* test;
};
template<typename Range1T>
StartsWith_T<Range1T> StartsWith(Range1T const& test) {
    return StartsWith_T<Range1T>(test);
}
template<typename T>
struct LexicalCaster {
    typedef T result_type;
    template<typename Input>
    T operator()(Input const& input) const {
        return boost::lexical_cast<T>(input);
    }
};
int main() {
    std::string stringToFilterBy("2");
    std::vector<std::string> input =
        boost::assign::list_of("1")("2")("22")("33")("222");
    std::vector<int> output;
    using namespace boost::adaptors;
    boost::copy(
        input
      | filtered(StartsWith(stringToFilterBy))
      | transformed(LexicalCaster<int>()),
        std::back_inserter(output));
}