Существует ли алгоритм STL / boost для проверки того, что все элементы в контейнере соответствуют значению? - PullRequest
15 голосов
/ 19 ноября 2010

Существует ли алгоритм STL / boost, который будет проверять, соответствуют ли все элементы между двумя итераторами заданному значению?Или, в качестве альтернативы, предикат возвращает true для всех них?

, то есть что-то вроде

template<class InputIterator, class T>
InputIterator all_match (InputIterator first, InputIterator last, const T& value)
{
    bool allMatch = true;
    while(allMatch && first!=last)
        allMatch = (value == *first++);
    return allMatch;
}

или

template <class InputIterator, class Predicate>
bool all_true (InputIterator first, InputIterator last, Predicate pred)
{
    bool allTrue = true;
    while (allTrue && first != last) 
        allTrue = pred(*first++);
    return allTrue;
}

Ответы [ 5 ]

22 голосов
/ 19 ноября 2010

Если вы можете отрицать предикат, вы можете использовать std :: find / std :: find_if и посмотреть, возвращает ли он конечный элемент вашей последовательности.Если нет, то он возвращает тот, который соответствует.

Вы можете адаптировать функцию с помощью std :: not1 или std :: not_equal_to, так что, комбинируя со std :: find_if, вы действительно можете сделать это, используя STL без записипетля.

bool allMatch = seq.end() == std::find_if( seq.begin(), seq.end(), 
    std::not_equal_to(val) );
bool allPass = seq.end() == std::find_if( seq.begin(), seq.end(), 
    std::not1(pred) );
18 голосов
/ 19 ноября 2010

C ++ 0x вводит std::all_of.

2 голосов
/ 19 ноября 2010

Вы можете использовать std::equal с предикатом.Что-то вроде:

using namespace std;
using namespace boost::lambda;

int main()
{
    vector<int> a;
    a.push_back(1);
    a.push_back(1);
    a.push_back(2);
    a.push_back(2);
    a.push_back(3);
    bool allMatch = equal(a.begin(), a.begin() + 2, a.begin(), _1 == 1);
    return 0;
}
2 голосов
/ 19 ноября 2010

Вы можете использовать std: find ord std :: find_if для этого.

template <class T>
struct pred {
    T t_;

    pred(const T& value) : t_(value) {}

    bool operator()(const T &t)
    {
        return t != t_;
    }
};

if (e.cend() == std::find_if(c.cbegin(), c.cend(), pred<T>(value)))
    print("all match value");
1 голос
/ 19 ноября 2010

Часто их можно просто посчитать:

template<class FwdIterator, class T>
InputIterator all_match (FwdIterator first, FwdIterator last, const T& value)
{
   return std::count(first, last, value) == std::distance(first, last);
}

Неэффективно, когда итератор не является случайным или когда он возвращает false. Не работает для входных итераторов.

...