在std :: list中查找所有匹配的元素

时间:2014-12-13 02:14:34

标签: c++ c++11 stdlist

我想知道是否有任何内置或完善的方式(即通过lambda)来浏览std :: list的元素并找到所有匹配给定值的元素?我知道我可以遍历所有这些,但我想我会问是否有办法让迭代器只迭代符合给定条件的元素?我下面的示例只给出了第一个匹配元素的迭代器。

#include <list>
#include <algorithm>
#include <stdio.h>

int main()
{
    std::list<int> List;
    List.push_back(100);
    List.push_back(200);
    List.push_back(300);
    List.push_back(100);
    int findValue = 100;

    auto it = std::find_if(List.begin(), List.end(), [findValue](const int value)
    {
        return (value == findValue);
    });

    if (it != List.end())
    {
        for (; it != List.end(); ++it)
        {
            printf("%d\n", * it);
        }
    }
    return 0;
}

感谢您的反馈。

4 个答案:

答案 0 :(得分:15)

boost::filter_iterator允许您仅使用满足谓词的iterable元素。给定谓词Pred和容器Cont

auto begin_iter = boost::make_filter_iterator(Pred, std::begin(Cont), std::end(Cont));
auto end_iter = boost::make_filter_iterator(Pred, std::end(Cont), std::end(Cont));

您现在可以使用begin_iterend_iter,就像它们是容器的开始和结束迭代器一样,只包含满足Cont的{​​{1}}元素。另一个额外的好处是你可以将迭代器包装在boost::iterator_range中并在期望可迭代对象的地方使用它,就像这样的基于范围的Pred循环:

for

特别是,将auto range = boost::make_iterator_range(begin_iter, end_iter); for(auto x : range) do_something(x); 设置为函数(可能是lambda),检查与固定值的相等性,将为您提供所需的迭代器。

答案 1 :(得分:12)

使用copy_ifiterators

#include <list>
#include <algorithm>
#include <iterator>
#include <iostream>

int main()
{
    std::list<int> List;
    List.push_back(100);
    List.push_back(200);
    List.push_back(300);
    List.push_back(100);
    int findValue = 100;

    std::copy_if(List.begin(), List.end(), std::ostream_iterator<int>(std::cout, "\n"), [&](int v) {
        return v == findValue;
    });
    return 0;
}

如果您不想直接输出结果并希望用匹配项填充另一个容器:

std::vector<int> matches;
std::copy_if(List.begin(), List.end(), std::back_inserter(matches), [&](int v) {
    return v == findValue;
});

答案 2 :(得分:9)

std::find_ifstd::find的概括,当你需要一个函数来检查你想要的元素时,而不是一个简单的相等测试。如果你只是想进行一个简单的相等测试,那么就不需要通用形式,而lambda只会增加复杂性和冗长性。只需使用std::find(begin, end, findValue)代替:

std::vector<std::list<int>::const_iterator> matches;
auto i = list.begin(), end = list.end();
while (i != end)
{
  i = std::find(i, end, findValue);
  if (i != end)
    matches.push_back(i++);
}

但是我不是在循环中调用find而是手动编写循环:

std::vector<std::list<int>::const_iterator> matches;
for (auto i = list.begin(), toofar = l.end(); i != toofar; ++i)
  if (*i == findValue)
    matches.push_back(i);

答案 3 :(得分:1)

std::partition使您可以简单地将所有与谓词匹配的元素移动到容器的前端(第一个分区)。返回值是一个指向第二个分区的第一个元素的迭代器(包含不匹配的元素)。这就是“过滤”容器所需的全部内容。