vectores tipos programacion libreria imprimir funciones ejemplos con cadenas arreglos arreglo c++ stl

programacion - tipos de arreglos en c++



usando STL para encontrar todos los elementos en un vector (7)

Tengo una colección de elementos sobre los que necesito operar, llamando funciones miembro en la colección:

std::vector<MyType> v; ... // vector is populated

Para las funciones de llamada sin argumentos es bastante directo:

std::for_each(v.begin(), v.end(), std::mem_fun(&MyType::myfunc));

Algo similar se puede hacer si hay un argumento para la función a la que deseo llamar.

Mi problema es que quiero llamar a una función en elementos en el vector si cumple alguna condición. std::find_if devuelve un iterador al primer elemento que cumple las condiciones del predicado.

std::vector<MyType>::iterator it = std::find_if(v.begin(), v.end(), MyPred());

Deseo encontrar todos los elementos que cumplan con el predicado y operar sobre ellos.

He estado buscando en los algoritmos STL un find_all " find_all " o " do_if ", o una forma en que puedo hacer esto con el STL existente (de modo que solo necesito iterar una vez), en lugar de hacer el mío o simplemente hacer una iteración estándar usando un bucle for y comparaciones.


Funciones de Lamda: la idea es hacer algo como esto

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

Publicación origial aquí .


Por lo que su valor para_each_if se está considerando como una eventual adición para impulsar. No es difícil implementar el tuyo.


Puedes usar Boost.Foreach :

BOOST_FOREACH (vector<...>& x, v) { if (Check(x) DoStuff(x); }


Boost Lambda lo hace fácil.

#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) ] );

Incluso podría eliminar la definición de MyPred (), si es simple. Aquí es donde realmente brilla lambda. Por ejemplo, si MyPred significaba "es divisible por 2":

std::for_each( v.begin(), v.end(), if_( _1 % 2 == 0 )[ std::mem_fun( &MyType::myfunc ) ] ); Actualización: Hacer esto con la sintaxis lambda C ++ 0x también es muy agradable (continuando con el predicado como módulo 2):

std::for_each( v.begin(), v.end(), [](MyType& mt ) mutable { if( mt % 2 == 0) { mt.myfunc(); } } );

A primera vista, esto parece un paso atrás de la sintaxis de boost :: lambda, sin embargo, es mejor porque la lógica de functor más compleja es trivial de implementar con la sintaxis de c ++ 0x ... donde cualquier cosa muy complicada en boost :: lambda se vuelve difícil con rapidez. Microsoft Visual Studio 2010 beta 2 actualmente implementa esta funcionalidad.


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); }

Para el registro, aunque he visto una implementación donde llamar a end() en una list era O (n), no he visto ninguna implementación de STL donde la llamada a end() en un vector fuera diferente de O (1) - principalmente porque se garantiza que los vector tienen iteradores de acceso aleatorio.

Aun así, si le preocupa un end() ineficiente end() , puede usar este código:

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); }


¿Está bien cambiar el vector? Es posible que desee ver el algoritmo de partición.
Algoritmo de partición

Otra opción sería cambiar su MyType::myfunc para verificar el elemento, o tomar un predicado como parámetro y usarlo para probar el elemento en el que está operando.


Escribí un for_each_if() y un for_each_equal() que hacen lo que creo que estás buscando.

for_each_if() toma un functor de predicado para evaluar la igualdad, y for_each_equal() toma un valor de cualquier tipo y hace una comparación directa usando operator == . En ambos casos, la función que pasa se invoca en cada elemento que pasa la prueba de igualdad.

/* --- 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; };