2011-04-03 20 views
21

Necesito una lista de cadenas y una forma de determinar rápidamente si una cadena está contenida dentro de esa lista.Mejor colección para búsqueda rápida de cadenas

Para mejorar la velocidad de búsqueda, consideré SortedList y Dictionary; sin embargo, ambos funcionan con KeyValuePair s cuando todo lo que necesito es un solo string.

Sé que podría usar un KeyValuePair y simplemente ignorar la parte Value. Pero prefiero ser eficiente y me pregunto si hay una colección que se adapte mejor a mis requisitos.

Respuesta

29

Si tiene .NET 3.5 o superior, use HashSet<String>.

En su defecto, un Dictionary<string, byte> (o cualquier tipo que desee para el parámetro TValue tipo) sería más rápido que un SortedList si usted tiene una gran cantidad de entradas - este último utilizará una búsqueda binaria, por lo que será O (log n) búsqueda, en lugar de O (1).

+1

fresco, gracias. (Aunque parece un poco extraño, tomó hasta 3,5 tener esa clase.) –

+0

@Jonathan: De acuerdo, así es la vida. En .NET 4 hay una interfaz para representar conjuntos ('ISet ') y también otra opción en 'SortedSet ' (que de nuevo no sería particularmente útil en este caso). –

+0

Estaba mirando hacia atrás en esto. Una búsqueda O (1) es realmente rápida. Sin embargo, supongo que esta colección implementa algún tipo de hash. Entonces, ¿O (1) no asume colisiones? (Por cierto, estoy trabajando en tu libro.) –

8

Si lo que desea saber si una cadena está en el uso conjunto HashSet<string>

5

Esto suena como un trabajo para

var keys = new HashSet<string>(); 

por MSDN: La función Contiene tiene O (1) complejidad.

Pero debe tener en cuenta que no da error para los duplicados al agregar.

+3

Para ser más precisos, el método Add no arroja una excepción pero devuelve true si la clave se agregó y false si ya estaba presente. –

+1

@Alois: suena perfecto. El hábito en gran parte de la biblioteca .NET de lanzar una excepción cada vez que algo no es así siempre me ha molestado. –

1

Sé que esta respuesta es un poco tarde para esta fiesta, pero me encontré con un problema en el que nuestros sistemas funcionaban con lentitud. Después del perfilado descubrimos que había MUCHAS búsquedas de cadenas sucediendo con la estructura de nuestras estructuras de datos.

Así que hicimos un poco de investigación, came across these benchmarks, hicimos nuestras propias pruebas, y ahora pasamos a utilizar SortedList.

if (sortedlist.ContainsKey(thekey)) 
{ 
//found it. 
} 

pesar de que un diccionario demostró ser más rápido, era menos código que teníamos que refactorizar, y el aumento de rendimiento era lo suficientemente bueno para nosotros.

De todos modos, quería compartir el sitio web en caso de que otras personas tengan problemas similares. Hacen comparaciones entre estructuras de datos donde la cadena que está buscando es una "clave" (como HashTable, Dictionary, etc.) o en un "valor" (Lista, Matriz, o en un Diccionario, etc.) que es donde están las nuestras almacenado

0

Sé que la pregunta es vieja como el infierno, pero tuve que resolver el mismo problema, solo para un conjunto muy pequeño de cadenas (entre 2 y 4).

En mi caso, en realidad utilicé la búsqueda manual en una serie de cadenas que resultó ser mucho más rápido que HashSet<string> (Lo evalué como punto de referencia).

for (int i = 0; i < this.propertiesToIgnore.Length; i++) 
{ 
    if (this.propertiesToIgnore[i].Equals(propertyName)) 
    { 
     return true; 
    } 
} 

¡Tenga en cuenta que es mejor que el conjunto de hash solo para arreglos pequeños!

EDIT: sólo funciona con un bucle manual de for, no use LINQ, detalles en los comentarios

+0

Sí, 'HashSet <>' tiene algunos gastos generales. Lo recomendaría solo cuando busque colecciones más grandes. Por cierto, su código podría acortarse a algo como 'return PropertiesToIgnore.Any (p => p.Equals (propertyName))' –

+0

Desafortunadamente, usar Linq ¡ralentiza la ejecución por un factor de 10! Resultados de la prueba 'ArrayManualLoop: 6.018 ns'' ArrayLinq: 59.171 ns'. Linq espinas la caché del procesador aparte, y todas las ganancias posibles se pierden. –

Cuestiones relacionadas