2010-12-02 18 views
6

¿Cuál es la mejor manera de filtrar todos los elementos en una estructura de datos que no obedecen a un determinado predicado? es decir, un método similar a los métodos de "filtro" en lenguajes de programación funcionales.Método de filtro para estructuras de datos C++

+1

posible duplicado de ["filtro" función de orden superior en C++] (http://stackoverflow.com/questions/3635260/filter-higher-order-function-in-c) – missingfaktor

Respuesta

5

STL tiene remove_if y remove_copy_if algoritmos.

+3

Y recuerde que "eliminar" en STL en realidad no elimina nada, simplemente empuja los indeseables a la parte posterior del autobús. ** Te estoy mirando, Rosa Parks! **;) Todavía tienes que llamar a 'container.erase (returnedIter, container.end())'. –

0

Esto 'debería' funcionar para cada clase de contenedor que tenga iteradores. Usando un puntero para mostrar que el contenedor se cambiará pasando por la función.

UnaryFunction necesita un tipo de retorno bool. Aunque el uso de las funciones propias STL podría ser más inteligentes ...

template <class Container, 
      class UnaryFunction> 
void filter(Container *container, UnaryFunction func) 
{ 
    typedef typename Container::iterator iter; // g++ complains w/o typename 
    for(iter elem(container->begin()); elem != container->end();) 
     elem = (func(&*elem)) ? (elem + 1) 
           : container->erase(elem); 
} 
+1

Sería mejor usar una referencia en lugar de un puntero (es más claro que la intención es modificar, no adquirir la propiedad). Además, esto sería bastante caro para los vectores, ya que para cada elemento único se eliminan todos los elementos desde esa posición hasta el final del vector, y también para los deques como la eliminación del medio es una operación costosa por básicamente las mismas razones. El único contenedor secuencial para el que esto es efectivo son las listas. –

+0

@Rodriguez - Bueno, el punto que traté de hacer con referencia fue que no se puede pasar por alto que está pasando en la matriz real con la declaración 'filter (& vec, someFunc)', mientras que'filter (vec, someFunc) 'podría engañar a algunos que no se molestan en mirar la declaración de la función. En segundo lugar, me doy cuenta de que este no es el código más oportuno para vectores o colas, pero el OP pidió específicamente una función de filtro que funcione en todas las estructuras de datos; esto hace justamente eso; podemos discutir sobre la eficiencia. Sin embargo, sus puntos son válidos y deben ser tomados en consideración por el OP. – IAE

+0

Y porque usa '(elem + 1)', solo funciona para contenedores de acceso aleatorio. (En primer lugar, los contenedores asociativos requerirían un bucle de borrado manual con una lógica diferente). – visitor

0

Si está utilizando impulso puede usar la biblioteca boost.iterator, que tiene filter_iterator para su caso. Incluso si no lo haces, es bastante fácil escribir el tuyo.