Para resolver este problema, la enumeración habitual no funcionará, porque sus asintóticas serán O(t*s). Por lo tanto, para las tareas de búsqueda de subcadenas, se utiliza el algoritmo KMP (Knuth-Morris-Pratt).
Para implementar este algoritmo se utiliza la función de prefijo de cadena, esta es una matriz de números de longitud n (strong>s longitud), en la que cada elemento es la longitud máxima del mayor sufijo propio de la subcadena s, coincidiendo con su prefijo. Por ejemplo:
Línea |
Función de prefijo |
Nota |
abababcab |
0 0 1 2 3 4 0 1 2 |
|
abcabcd |
0 0 0 1 2 3 0 |
|
aabaaab |
0 1 0 1 2 2 3 |
|
Algoritmo de función de prefijo trivial con asintóticas O(n^3):
vector<int> función_prefijo (cadena s) {
int n = (int ) s.longitud();
vector<int>pi(n);
para (int i=0; i<n; ++i)
para (int k=0; k<=i; ++k)
si (s.substr(0,k) == s .substr(i-k+1,k))
pi[i] = k;
regresarpi;
}
Y ahora necesitamos hacer una función de prefijo para una cadena de la forma: & nbsp; t + # + s, donde # es un carácter delimitador que claramente no está en el texto. Al analizar los valores de la función de prefijo después del carácter separador correspondiente, se debe tener en cuenta que si el valor resultante es igual a la longitud de la subcadena deseada, entonces se encuentra su aparición. Por ejemplo, para la cadena "abababcab" y la subcadena deseada "abab", la función de prefijo será:
0 0 1 2 0 1 2 3 4 3 4 0 1 2 necesitamos analizar los elementos de la cadena correspondiente s:
1 2 3 4 3 4 0 1 2 - hay dos casos en los que el valor es 4 (4º y 6º), es decir longitud t, como resultado, la respuesta debe escribirse: 4 - 4 (longitud t) & nbsp; = 0 y 6 - 4 = 2. Se puede ver que estas son las respuestas correctas y la cadena "abab" es en realidad una subcadena en la cadena "abababcab" en las posiciones 0 y 2.