【问题标题】:How can I filter a vector of strings in C++?如何在 C++ 中过滤字符串向量?
【发布时间】:2017-12-01 04:31:09
【问题描述】:

我有一个包含 10000 个字符串的大向量:

std::vector<std::string> v;
for (int i = 0; i < 10000; i++) { v.push_back(generateRandomString(10)); }

我想显示包含“AB”作为子字符串的字符串。我试过了:

std::vector<std::string> res;
res = std::copy_if(v, [](auto s) { return s.find("AB") != std::string::npos; });

cout << res;

但我收到以下错误:

错误:没有匹配函数调用 'copy_if(std::vectorstd::__cxx11::basic_string&, main(int, char**)::)' std::vectorstd::string b = std::copy_if(a, [](auto s) { return s.find("AB") != std::string::npos; });

如何过滤字符串向量并仅显示那些将“AB”作为子字符串的字符串?

(如果v 包含 50MB 的数据,这会有效吗?)

【问题讨论】:

标签: c++ string algorithm vector filter


【解决方案1】:

类似的东西(未经测试):

std::copy_if(v.begin(), v.end(),
    std::ostream_iterator<std::string>(std::cout, "\n"),
    [](const std::string& s) { return s.find("AB") != std::string::npos; });

【讨论】:

  • 感谢您的回答。我得到error: 'ostream_iterator' is not a member of 'std'
  • 如果你想复制到另一个向量,你可能想使用std::back_inserter而不是std::ostream_iterator
  • 你是否包含了the documentation建议在使用std::ostream_iterator之前应该包含的标题?
  • @vu1p3n0x OP:“我想显示那些......”强调我的。
  • @IgorTandetnik,为了进一步使用,我确实想将其复制到res,然后显示res
【解决方案2】:

如果您正在寻找仅打印您感兴趣的字符串的有效解决方案,则应避免创建中间数据结构,即不应使用std::copy_if。由于C++20,您可以将Ranges library 中的范围适配器std::views::filterrange-based for loop 一起使用,如下所示:

auto ab = [](const auto& s) { return s.find("AB") != std::string::npos; };
for (auto const& s : v | std::views::filter(ab))
    std::cout << s << std::endl;

此解决方案不会为过滤后的字符串创建临时向量,因为视图适配器会创建一个不包含元素的范围。结果范围只是向量v 的视图,但具有自定义的迭代行为。

C++23 开始,您可以使用std::string::contains 使代码更短且更具可读性,如下所示:

auto ab = [](const auto& s) { return s.contains("AB"); };
for (auto const& s : v | std::views::filter(ab))
    std::cout << s << std::endl;

Code on Wandbox

但是,如果您还想存储过滤后的结果以供进一步使用,则可以将上述解决方案与algorithms library中的std::ranges::copy结合起来,如下所示:

std::vector<std::string> res;
std::ranges::copy(v | std::views::filter(ab), std::back_inserter(res));
for (auto const& s : res)
    std::cout << s << std::endl;

Code on Wandbox

【讨论】:

    猜你喜欢
    • 2018-09-28
    • 1970-01-01
    • 2020-03-31
    • 1970-01-01
    • 2018-05-14
    • 2023-03-17
    • 2019-05-02
    • 1970-01-01
    • 2021-02-07
    相关资源
    最近更新 更多