A algoritmo típico sería el siguiente, con índices de cadena que van de 0 a M-1.
Devuelve la posición de la coincidencia o -1 si no se encuentra.
foreach hpos in range 0 thru len(haystack)-len(needle):
found = true
foreach npos in range 0 thru len(needle):
if haystack[hpos+npos] != needle[npos]:
found = false
break
if found:
return hpos
return -1
Tiene un rendimiento razonable, ya que sólo comprueba el mayor número de caracteres en cada posición pajar, según sea necesario para descubrir que no hay posibilidad de un partido.
No es necesariamente el algoritmo más eficiente, pero si su entrevistador espera que sepa todos los algoritmos de alto rendimiento fuera de la cabeza, están siendo poco realistas (es decir, tontos). Un buen desarrollador conoce bien los conceptos básicos, y cómo averiguar las novedades donde sea necesario (por ejemplo, cuando hay un problema de rendimiento, no antes).
El rendimiento varía entre O (a) y O (ab) dependiendo de los datos reales en las cadenas, donde a y b son las longitudes de pajar y aguja, respectivamente.
Una posible mejora es almacenar, dentro del bucle npos, la primera ubicación mayor que hpos, donde el carácter coincide con el primer carácter de la aguja.
De esta manera puede omitir hpos en la siguiente iteración ya que sabe que no puede haber coincidencia antes de ese punto. Pero nuevamente, eso puede no ser necesario, dependiendo de sus requisitos de rendimiento. Debe calcular el equilibrio entre la velocidad y el mantenimiento usted mismo.
Llegué a la mitad escribiendo una respuesta cuando vi esto, leí el artículo y me di cuenta de que era lo mismo. Nunca había oído hablar de eso antes, pero utilicé algo parecido para una máquina de estado de emparejamiento de patrón binario en '94. Oh bien. –