Фильтр std :: vector из std :: string’s

Как я могу создать выходной вектор, который фильтрует входной вектор на основе того, начинается ли он с определенной подстроки или нет. Я использую C ++ 98 и Boost.

Это насколько я получил:

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) );

3

Решение

Ты можешь использовать станд :: 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")));
4

Другие решения

Одним из способов является:

#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));
}
4

По вопросам рекламы [email protected]