I have a big vector of 10000 strings:
std::vector<std::string> v;
for (int i = 0; i < 10000; i++) { v.push_back(generateRandomString(10)); }
I'd like to display the strings which contain "AB" as a substring. I tried:
std::vector<std::string> res;
res = std::copy_if(v, [](auto s) { return s.find("AB") != std::string::npos; });
cout << res;
But I get the following error:
error: no matching function for call to 'copy_if(std::vectorstd::__cxx11::basic_string<char >&, main(int, char**)::<lambda(auto:1)>)' std::vectorstd::string b = std::copy_if(a, [](auto s) { return s.find("AB") != std::string::npos; });
How can I filter a vector of strings and display only those which have "AB" as a substring?
(Will this be efficient if v
contains 50MB of data?)
Something along these lines (untested):
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; });
If you are looking for an efficient solution for just printing the strings you are interested in, you should avoid creating an intermediate data structure, ie you shouldn't use std::copy_if
. Since C++20 you can use the range adaptor std::views::filter
from the Ranges library together with a range-based for loop , as follows:
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;
This solution does not create a temporary vector for the filtered strings, because the view adaptor creates a range that doesn't contain elements. The resulting range is just a view over the vector v
, but with a customized iteration behavior.
As of C++23 you can use std::string::contains to make the code even shorter and more readable, as follows:
auto ab = [](const auto& s) { return s.contains("AB"); };
for (auto const& s : v | std::views::filter(ab))
std::cout << s << std::endl;
However, if you want to also store the filtered result for further use, then you can combine the above solution with std::ranges::copy
from the algorithms library , as follows:
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;
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.