Tarea
La tarea es desarrollar un algoritmo de coincidencia de cadena exacto en tiempo real de su elección.
Entrada
Se proporcionan dos líneas de texto en la entrada estándar, separadas por una nueva línea. La primera línea contiene el "patrón" y simplemente será una cadena ASCII extraída de las letras a-z
.
La segunda línea contiene el "texto" más largo y también será simplemente una cadena ASCII extraída de las letras a-z
.
Salida
Una lista de índices de dónde ocurren las coincidencias exactas. Debes mostrar la posición del inicio de cada partido que ocurra.
Especificación
Su algoritmo puede pasar tiempo lineal preprocesando el patrón. Luego debe leer el texto de izquierda a derecha y tomar un tiempo constante para cada carácter en el texto y generar cualquier nueva coincidencia tan pronto como ocurra. Los partidos pueden, por supuesto, superponerse entre sí.
Algoritmo
Hay muchos algoritmos de coincidencia exacta en tiempo real. Uno se menciona en la wiki para KMP, por ejemplo. Puede usar cualquiera que desee, pero siempre debe generar la respuesta correcta.
Mantendré una tabla de líderes por idioma para que aquellos que prefieren los idiomas populares también puedan ganar a su manera. Explica qué algoritmo has implementado.
Tiempo real
Parece que ha habido mucha confusión sobre lo que significa el tiempo real. No significa simplemente tiempo lineal. Entonces, el KMP estándar no es en tiempo real. El enlace en la pregunta apunta explícitamente a una parte de la página wiki de KMP sobre una variante en tiempo real de KMP. Tampoco lo es Boyer-Moore-Galil en tiempo real. Esta pregunta / respuesta histórica discute el problema o se puede buscar en Google "coincidencia exacta en tiempo real" o términos similares.
fuente
abcd
yacbdefg
, saldría1 4
, paraa
yd
?a
y eld
partido. Hayabcd
yacbdefg
, y ela
yd
están en posiciones idénticas.Respuestas:
Python 2, 495 bytes
Este es un KMP en tiempo real, que es mucho más corto y solo un poco más lento que el algoritmo BMG (que generalmente es sublineal). Llamar con
K(pattern, text)
; La salida es idéntica al algoritmo BMG.fuente
Python 2, 937 bytes
Esto no es corto, de ninguna manera, pero (a) funciona, (b) cumple con todos los requisitos, y (c) se juega al golf tanto como sea posible.
Esta es una implementación del algoritmo Boyer-Moore-Galil. Bastante sencillo: llame con
S(pattern,text)
; Las otras dos funciones se utilizan en el preprocesamiento. De hecho, todo menos las últimas 5 líneas es un preprocesamiento.Un ejemplo de ejecución, que tomó alrededor de un segundo:
fuente
O(m)
preprocesamiento yO(n)
coincidencia [=>O(n+m)
], lo que hace (o mejor).O(n+m)
tiempo pero tomar n tiempo para uno de los símbolos en el texto, por ejemplo.KMP, Python 2 (213 bytes)
Versión sin golf. El primer bucle es construir el autómata KMP. El segundo ciclo es caminar sobre los autómatas. Comparten casi el mismo patrón, pero abstraerlos costará más bytes, por lo que para un código de golf prefiero duplicar esta lógica. Una implementación similar se usa ampliamente en la programación de concursos.
fuente
KMP en tiempo real, Python 2 (167 bytes)
En KMP normal, simulamos el comportamiento del autómata mediante el uso de una función de falla. En este KMP en tiempo real, el autómata completo se construye de modo que en la frase correspondiente pueda procesar cada carácter en tiempo real (tiempo constante).
El tiempo de preprocesamiento y la complejidad del espacio es O (nm), donde m es el tamaño del alfabeto yn es la longitud de la cadena del patrón. Sin embargo, en mis pruebas, el tamaño real de la tabla de transición siempre es inferior a 2n, por lo que tal vez podamos demostrar que la complejidad de tiempo y espacio es O (n).
Versión sin golf
fuente
Q, 146 bytes
Prueba
genera 15 y 34
Notas
No se limita al alfabeto (admite cualquier carácter ascii y distingue entre mayúsculas y minúsculas).
No utiliza ninguna de las operaciones específicas definidas por Q sobre cadenas -> funciona en cadenas como secuencias (ops match, length, etc.)
Minimiza la tabla de transición uniendo todos los caracteres que no están en el patrón como una clase de caracteres única.
Puedo exprimir un poco el código. Es un primer intento de validar la estrategia de solución.
Visite cualquier carácter del texto exactamente una vez, y para cada carácter de entrada hay un salto único. Así que supongo que la búsqueda se ajusta como 'tiempo real'
La construcción de tablas al estado i y char c buscan la subcadena más larga que termina en i y después de agregar c es un prefijo de S. La construcción no está optimizada, por lo que no sé si es válida
El formato de entrada no encaja bien con el idioma. Pasar dos argumentos de cadena ahorrará 16 bytes
Explicación
W global representa un patrón y S corresponde al texto a buscar
x:1_"\n "\:x
código extraño para hacer frente a los requisitos de entrada (Q requiere que las cadenas multilínea thtat tengan sangrías que no sean las primeras líneas, por lo que debe descartar el espacio adicional frente a cada línea que no sea la primera)n::#W
calcula la longitud W y guarda como n globalu::?W
calcula caracteres únicos en W y los guarda como global uu?S
genera la clase characted para cada personaje de SConstruya una tabla de transición T con una fila por carácter único en W (más un extra) y una columna para cada índice en W (más un extra). La fila adicional corresponde al estado inicial, y la columna adicional recoge cualquier carácter en S pero no en W. Esta estrategia minimiza el tamaño de la tabla
p:{$[n<#x;0;x~(#x)#W;#x;0]}
es la función que busca el prefijo más largof:{{|/p'x}'((1_)\x#W),\:/:u}
es la función que calcula una fila x de TBuscar texto usando la tabla de transición.
T\[0;u?S]
itera sobre 0 (estado inicial) y cada una de las clases de caracteres de S, utilizando como nuevo valor el valor en la tabla de transición T [estado] [charClass]. Los estados finales tienen el valor n, por lo que buscamos ese valor en la secuencia de estados y lo devuelve ajustado (para indicar la posición inicial en lugar de la posición final de cada coincidencia)fuente
Boyer-Moore, Perl (50)
Perl intenta usar Boyer-Moore naturalmente:
fuente