verificar si un std::vector contiene un objeto determinado? [duplicate]

4 minutos de lectura

avatar de usuario
jmasterx

¿Hay algo en <algorithm> que le permite verificar si un contenedor std:: contiene algo? O, una forma de hacer uno, por ejemplo:

if(a.x == b.x && a.y == b.y)
return true;

return false;

¿Se puede hacer esto sólo con std::map como usa llaves?

Gracias

  • ¿Si contiene algo específico, o simplemente no está vacío?

    – James Curran

    10 de agosto de 2010 a las 15:54

  • ¿Qué referencia de C++ estás usando? Y el encabezado se llama <algorithm> – nota n.º .h.

    luego

    10 de agosto de 2010 a las 15:54


  • Algo específico, como una estructura personalizada.

    – jmasterx

    10 de agosto de 2010 a las 15:56

  • si el contenedor contiene una estructura personalizada, deberá implementar operator== para compararlos; después std::find trabajará.

    –Mike Seymour

    10 de agosto de 2010 a las 16:13

  • Como respondió en el duplicado, creo que lo más elegante es usar boost::algorithm::any_of_equal.

    – ingomueller.net

    25 de julio de 2018 a las 10:58


avatar de usuario

Comprobando si v contiene el elemento x:

#include <algorithm>

if(std::find(v.begin(), v.end(), x) != v.end()) {
    /* v contains x */
} else {
    /* v does not contain x */
}

Comprobando si v contiene elementos (no está vacío):

if(!v.empty()){
    /* v is non-empty */
} else {
    /* v is empty */
}

  • ¿Qué pasa si x es el último elemento en v?

    – David Carpintero

    5 de diciembre de 2012 a las 1:38

  • David, end() apunta a uno más allá del último elemento, por lo que todo funciona.

    –Mark Beckwith

    14 de enero de 2013 a las 20:08

  • ¿Esto tiene en cuenta la tolerancia numérica cuando se trata de determinar si hay un doble en el vector?

    – Nicolás Hamilton

    20 de agosto de 2015 a las 7:18

  • @NicholasHamilton: No, usa operator==. Si necesita tener en cuenta la tolerancia numérica, utilice std::find_if y proporcionar un predicado adecuado.

    – Tú

    20 de agosto de 2015 a las 18:38

  • @DarnocEloc: No.

    – Tú

    6 de agosto de 2020 a las 7:58

avatar de usuario
AshleysBrain

Si buscar un elemento es importante, recomendaría std::set en vez de std::vector. Usando esto:

std::find(vec.begin(), vec.end(), x) corre en tiempo O(n), pero std::set tiene su propio find() miembro (es decir myset.find(x)) que se ejecuta en tiempo O (log n), que es mucho más eficiente con una gran cantidad de elementos

std::set también garantiza que todos los elementos agregados sean únicos, lo que le evita tener que hacer algo como if not contained then push_back()....

  • ¡¡¡Excelente!!! Estoy escribiendo un lexer. Los conjuntos serán mucho mejores que los vectores. Lo hace set tener un count método como map? También quiero poder obtener el índice del elemento en un conjunto.

    – Resumen

    03/04/2015 a las 12:30


  • ¡Excelente información! Gracias por responder a la pregunta directa y proporcionar una solución adicional.

    – CodeMouse92

    18 de junio de 2015 a las 3:10

  • Este es un mal consejo. Si el rendimiento es importante, perfil. No hay garantía alguna de que el análisis de complejidad tenga algo que decir sobre su problema específico.

    – Andreas Haferburg

    2 de septiembre de 2016 a las 11:24


  • Depende del número de elementos. Las características de búsqueda de std::set funcionan muy bien para contenedores con una gran cantidad de elementos a costa de la localidad de los datos. Debe realizar un análisis de rendimiento (por ejemplo, creación de perfiles) para decidir qué tan alto es lo suficientemente alto para cambiar de una estructura de datos vectoriales a una estructura de datos establecida.

    – Burak Arslán

    3 oct 2016 a las 7:30

  • @Segmentation La notación O(n) no se trata de los peores casos. HASTA DONDE SE, set no funciona como un vector en absoluto. La mayoría set Las implementaciones usan árboles rojo-negro, que tienen una sobrecarga significativa. No sé a qué te refieres con un encabezado que agrega gastos generales. La sobrecarga generalmente se refiere a la sobrecarga del tiempo de ejecución. Los mejores casos de uso de set son “Me siento perezoso y no quiero pensar en eso” y “Necesito hacer esto rápido”. Si te preocupa el rendimiento, debes crear un perfil. unordered_set podría valer la pena intentarlo.

    – Andreas Haferburg

    1 de abril de 2019 a las 9:41


avatar de usuario
neildurant

Consulte la pregunta: ¿Cómo encontrar un elemento en un std::vector?

También deberá asegurarse de haber implementado un operator==() para su objeto, si el predeterminado no es suficiente para una prueba de igualdad “profunda”.

  • Normalmente no implementaría una costumbre operator==() para que mi clase solo pueda usar std::find() una o dos veces. Solo haría eso si realmente tiene sentido agregar esa anulación a la interfaz pública de su clase. Necesidad de poder utilizar std::find() no justifica eso. Además, ¿qué sucede si necesita hacer std::find() dos veces pero necesita comparar sus objetos de una manera diferente? ¿Como en una propiedad diferente?

    – Júpiter

    10 abr 2019 a las 22:55

  • si te preocupa implementar el operator==entonces recomendaría usar std::find_ifentonces podría tener predicados reutilizables para sus diferentes casos de criterios

    – yano

    21 de noviembre de 2019 a las 23:57

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad