Para el siguiente bloque de código:
For I = 0 To listOfStrings.Count - 1
If myString.Contains(lstOfStrings.Item(I)) Then
Return True
End If
Next
Return False
El resultado es:
Caso 1:
myString: C:\Files\myfile.doc
listOfString: C:\Files\, C:\Files2\
Result: True
Caso 2:
myString: C:\Files3\myfile.doc
listOfString: C:\Files\, C:\Files2\
Result: False
La lista (listOfStrings) puede contener varios elementos (mínimo 20) y debe verificarse con miles de cadenas (como myString).
¿Hay alguna forma mejor (más eficiente) de escribir este código?
fuente
cuando construyes las tuyas debería ser así
fuente
Hubo una serie de sugerencias de una pregunta similar anterior "La mejor manera de probar la cadena existente en una gran lista de comparables ".
Regex podría ser suficiente para su requerimiento. La expresión sería una concatenación de todas las subcadenas candidatas, con un
|
operador OR " " entre ellas. Por supuesto, tendrá que tener cuidado con los caracteres sin escape al construir la expresión, o si no se compila debido a la complejidad o las limitaciones de tamaño.Otra forma de hacer esto sería construir una estructura de datos trie para representar todas las subcadenas candidatas (esto puede duplicar algo lo que está haciendo el comparador de expresiones regulares). A medida que avanza por cada carácter en la cadena de prueba, crearía un nuevo puntero a la raíz del trie y avanzaría los punteros existentes al niño apropiado (si lo hubiera). Obtienes una coincidencia cuando cualquier puntero alcanza una hoja.
fuente
Me gustó la respuesta de Marc, pero necesitaba que la coincidencia Contains fuera CaSe InSenSiTiVe.
Esta fue la solución:
fuente
Según sus patrones, una mejora sería cambiar a usar StartsWith en lugar de Contains. StartsWith solo necesita iterar a través de cada cadena hasta que encuentre la primera falta de coincidencia en lugar de tener que reiniciar la búsqueda en cada posición de carácter cuando encuentre una.
Además, según sus patrones, parece que puede extraer la primera parte de la ruta de myString, luego invertir la comparación, buscando la ruta de inicio de myString en la lista de cadenas en lugar de al revés.
EDITAR : Esto sería aún más rápido utilizando la idea HashSet que menciona @Marc Gravell ya que podría cambiar
Contains
aContainsKey
y la búsqueda sería O (1) en lugar de O (N). Tendría que asegurarse de que las rutas coincidan exactamente. Tenga en cuenta que esta no es una solución general como la de @Marc Gravell, sino que se adapta a sus ejemplos.Perdón por el ejemplo de C #. No he tenido suficiente café para traducir a VB.
fuente
Vieja pregunta Pero como
VB.NET
era el requisito original. Usando los mismos valores de la respuesta aceptada:fuente
¿Has probado la velocidad?
es decir, ¿ha creado un conjunto de datos de muestra y lo ha perfilado? Puede que no sea tan malo como crees.
¡Esto también podría ser algo que podría generar en un hilo separado y dar la ilusión de velocidad!
fuente
Si la velocidad es crítica, es posible que desee buscar el algoritmo Aho-Corasick para conjuntos de patrones.
Es un trie con enlaces de falla, es decir, la complejidad es O (n + m + k), donde n es la longitud del texto de entrada, m la longitud acumulativa de los patrones yk el número de coincidencias. Solo tiene que modificar el algoritmo para terminar después de encontrar la primera coincidencia.
fuente
fuente
El inconveniente del
Contains
método es que no permite especificar el tipo de comparación, que a menudo es importante al comparar cadenas. Siempre es sensible a la cultura y a mayúsculas y minúsculas. Así que creo que la respuesta de WhoIsRich es valiosa, solo quiero mostrar una alternativa más simple:fuente