используя STL, чтобы найти все элементы в векторе

из исходного кода BeautifulSoup:

http://bazaar.launchpad.net/~leonardr/beautifulsoup/bs4/view/head:/bs4/element.py#L1260

def find_all(self, name=None, attrs={}, recursive=True, text=None,
                 limit=None, **kwargs):
# ...
# ...

findAll = find_all       # BS3
findChildren = find_all  # BS2

13
задан twokats 24 October 2008 в 17:27
поделиться

7 ответов

Лямбда повышения делает это легким.

#include <boost/lambda/lambda.hpp>
#include <boost/lambda/bind.hpp>
#include <boost/lambda/if.hpp>

std::for_each( v.begin(), v.end(), 
               if_( MyPred() )[ std::mem_fun(&MyType::myfunc) ] 
             );

Вы могли даже покончить с определением MyPred (), если это просто. Это - то, где лямбда действительно сияет. Например, если MyPred имел в виду, "является делимым 2":

std::for_each( v.begin(), v.end(), 
               if_( _1 % 2 == 0 )[ std::mem_fun( &MyType::myfunc ) ]
             );

<час> Обновление: Выполнение этого с C++ 0x синтаксис лямбды также очень хорошо (продолжать предикат как по модулю 2):
std::for_each( v.begin(), v.end(),
               [](MyType& mt ) mutable
               {
                 if( mt % 2 == 0)
                 { 
                   mt.myfunc(); 
                 }
               } );

На первый взгляд это похоже на шаг назад от повышения:: синтаксис лямбды, однако, это лучше, потому что более сложная логика функтора тривиальна для реализации с C++ 0x синтаксиса... где что-либо очень сложное в повышении:: лямбда становится хитрой быстро. Бета 2 Microsoft Visual Studio 2010 года в настоящее время реализует эту функциональность.

20
ответ дан paxos1977 24 October 2008 в 17:27
поделиться

Он в порядке для изменения вектора? Можно хотеть посмотреть на алгоритм раздела.
алгоритм Раздела

Другая опция состояла бы в том, чтобы изменить Ваш MyType::myfunc, чтобы или проверить элемент, или взять предикат в качестве параметра и использовать его для тестирования элемента, на который это воздействует.

6
ответ дан Marcin 24 October 2008 в 17:27
поделиться

Поскольку, чем стоимостью в for_each_if рассматривают как возможное дополнение к повышению. Не трудно реализовать Ваше собственное.

0
ответ дан Greg Rogers 24 October 2008 в 17:27
поделиться
  • 1
    А-ч, интересный. Я так или иначе didn' t узнают об этом только после чтения ключевого слова " drop" здесь, который теперь заставляет меня думать, является ли R отбрасывание размеров хорошей идеей или нет. I' чтение ll на этом. – slhck 31 October 2012 в 11:14

Я записал for_each_if() и for_each_equal(), которые делают то, что я думаю, что Вы ищете.

for_each_if() берет функтор предиката для оценки равенства, и for_each_equal() принимает значение любого типа и делает прямое сравнение с помощью operator ==. В обоих случаях функция, в которой Вы передаете, вызвана на каждом элементе, который проходит тест равенства.

/* ---

    For each
    25.1.1

        template< class InputIterator, class Function, class T>
            Function for_each_equal(InputIterator first, InputIterator last, const T& value, Function f)

        template< class InputIterator, class Function, class Predicate >
            Function for_each_if(InputIterator first, InputIterator last, Predicate pred, Function f)

    Requires:   

        T is of type EqualityComparable (20.1.1) 

    Effects:    

         Applies f to each dereferenced iterator i in the range [first, last) where one of the following conditions hold:

            1:  *i == value
            2:  pred(*i) != false

    Returns:    

        f

    Complexity: 

        At most last - first applications of f

    --- */

    template< class InputIterator, class Function, class Predicate >
    Function for_each_if(InputIterator first, 
                         InputIterator last, 
                         Predicate pred, 
                         Function f)
    {
        for( ; first != last; ++first)
        {
            if( pred(*first) )
                f(*first);
        }
        return f;
    };

    template< class InputIterator, class Function, class T>
    Function for_each_equal(InputIterator first, 
                            InputIterator last, 
                            const T& value, 
                            Function f)
    {
        for( ; first != last; ++first)
        {
            if( *first == value )
                f(*first);
        }
        return f;
    };
12
ответ дан John Dibling 24 October 2008 в 17:27
поделиться
std::vector<int> v, matches;
std::vector<int>::iterator i = v.begin();
MyPred my_pred;
while(true) {
    i = std::find_if(i, v.end(), my_pred);
    if (i == v.end())
        break;
    matches.push_back(*i);
}

Для записи, в то время как я видел реализацию, где вызов end() на list был O (n), я не видел реализаций STL, где вызов end() на vector был чем-либо кроме O (1) - главным образом, потому что vector с, как гарантируют, будут иметь итераторы произвольного доступа.

, Несмотря на это, если Вы волнуетесь по поводу неэффективного end(), можно использовать этот код:

std::vector<int> v, matches;
std::vector<int>::iterator i = v.begin(), end = v.end();
MyPred my_pred;
while(true) {
    i = std::find_if(i, v.end(), my_pred);
    if (i == end)
        break;
    matches.push_back(*i);
}
1
ответ дан Max Lybbert 24 October 2008 в 17:27
поделиться

Функции Lamda - идея состоит в том, чтобы сделать что-то вроде этого

for_each(v.begin(), v.end(), [](MyType& x){ if (Check(x) DoSuff(x); })  

сообщение Origial здесь .

0
ответ дан computinglife 24 October 2008 в 17:27
поделиться
  • 1
    Я думаю, что все уже задали этот вопрос. Согласие богов R состояло в том, что это значение по умолчанию не было так хорошо, но что оно не может быть изменено без obsoleting большая часть существующего кода. Будет исправлен в Q. – Dieter Menne 31 October 2012 в 17:06

Можно использовать Повышение. Foreach:

BOOST_FOREACH (vector<...>& x, v)
{
    if (Check(x)
        DoStuff(x);
}
0
ответ дан Ferruccio 24 October 2008 в 17:27
поделиться
Другие вопросы по тегам:

Похожие вопросы: