2010-06-08 24 views
6

¿cuál es la alternativa?por qué no hay ningún vector para encontrar en C++

¿Debo escribir por mi cuenta?

+1

Tal vez deba definir lo que "buscar" está destinado a hacer? – KevenK

+20

Hay un 'std :: find'. Consulte http://stackoverflow.com/questions/571394/how-to-find-an-item-in-a-stdvector/571405#571405 – meagar

+13

La belleza de la STL radica en el __desacoplamiento de contenedores y algoritmos__, hecho pegando ellos junto con iteradores. Esa es una decisión deliberada de diseño, que conduce a "abstracciones más grandes" que todas las bibliotecas de OO que he visto. Si vienes de un fondo OO más estricto (Java, C#), puede parecer extraño al principio, pero _ definitivamente vale la pena aprender_. – sbi

Respuesta

41

No es el algoritmo std::find(), que realiza una búsqueda lineal en un intervalo iterador, por ejemplo,

std::vector<int> v; 

// Finds the first element in the vector that has the value 42: 
// If there is no such value, it == v.end() 
std::vector<int>::const_iterator it = std::find(v.begin(), v.end(), 42); 

Si se ordena su vector, puede utilizar std::binary_search() para probar si un valor está presente en el vector, y std::equal_range() para obtener iteradores de inicio y fin en el rango de elementos en el vector que tienen ese valor.

+3

La ventaja de tener 'std :: find' como una función libre es que funcionará sobre una matriz de memoria, un' std :: vector' o cualquier otro contenedor que se pueda atravesar linealmente. – Thanatos

+0

Sin embargo, podría "multi-hilo". –

+0

Solo verías una mejora constante del factor. Además, está fuera del alcance de lo que hace 'std :: find'. (En la mayoría de las situaciones, no es necesario encontrar varios subprocesos). Sin embargo, podría escribir un 'parallel_find()' que funcionó de manera muy similar y funcionaría en todos los contenedores que cumplieran con un conjunto de requisitos (bastante flojos). – Thanatos

4

Use std::find(vec.begin(), vec.end(), value).

Y no se olvide de incluyen<algorithm>

8

¿Quién te dijo eso? Hay un algoritmo de "búsqueda" para vector en C++. Irónicamente Coincidentemente, se llama std::find. O tal vez std::binary_search. O algo más, dependiendo de las propiedades de los datos almacenados en su vector.

Los contenedores obtienen sus propias versiones específicas de algoritmos genéricos (implementados como métodos de contenedor) solo cuando la implementación efectiva del algoritmo está de alguna manera vinculada a los detalles internos del contenedor. std::list<>::sort sería un ejemplo.

En todos los demás casos, los algoritmos se implementan mediante funciones independientes.

+0

Perdón por nitpick, pero ¿qué tiene de irónico que una función de búsqueda se llame "encontrar"? – jalf

+0

@jalf: Supongo que fue intencionalmente sarcástica ... señalando que el OP se queja de que no hay "encontrar" cuando hay "buscar" y una búsqueda en Google para "C++ encontrar" devuelve el segundo resultado como un enlace a ' std :: find' en cplusplus.com – KevenK

+3

Llamar sarcásticamente a algo irónico ... Hombre, eso es profundo. ;) – jalf

21

La razón no hay vector::find se debe a que no hay ninguna ventaja sobre algorítmica std::find (std::find es O(N) y, en general, no se puede hacer mejor por vectores).

Pero la razón por la que tiene map::find es porque puede ser más eficiente (es map::findO(log N) por lo que siempre querría usar que más std::find para los mapas).

+0

Sin duda, puedes hacerlo mejor que O (N) si el vector está ordenado. – moodboom

2

¿cuál es la alternativa?

El estándar ofrece std :: find, para búsqueda secuencial en secuencias arbitrarias de elementos similares (o algo así).

Esto se puede aplicar a todos los contenedores que admiten iteradores, pero para contenedores ordenados internamente (como std::map) la búsqueda se puede optimizar. En ese caso, el contenedor ofrece su propia función de miembro find.

¿Por qué no hay ningún vector para encontrar en C++?

No tenía sentido crear std::vector<???>::find ya que la implementación sería idéntica a std::find(vector.begin(), vector.end(), value_to_find);.

¿Debo escribir yo mismo?

No.A menos que tenga limitaciones o requisitos específicos, debe usar la implementación de STL siempre que sea posible.

3

Tener una funcionalidad 'buscar' en la clase contenedor viola 'SRP' (principio de responsabilidad única). La funcionalidad principal de un contenedor es proporcionar interfaces para el almacenamiento, recuperación de elementos en el contenedor. 'Encontrar', 'Ordenar', 'Iterar', etc. no son funciones básicas de ningún contenedor y, por lo tanto, no forman parte de su interfaz directa.

Sin embargo, como estados 'Herb' en Namespace Principle, 'find' es una parte de la interfaz al definirse en el mismo espacio de nombres como 'vector', es decir 'std'.

+1

Sin embargo, es totalmente apropiado que un contenedor proporcione su propia función 'find' _if_ puede proporcionar uno que rinda mejor que el algoritmo genérico' std :: find' (considere 'std :: map :: find'). –

Cuestiones relacionadas