Algoritmo KPM de Python

Descripción del punto de conocimiento:

Hablemos primero de los prefijos y sufijos.

Por ejemplo, hay una cadena: abab

Entonces el subíndice es 3 (el prefijo y el sufijo son ambos 1 menos que la longitud del subíndice, donde el subíndice es 3 y la longitud es 4)

Los prefijos son: a, ab, aba

El sufijo es: b, ba, bab

1. Para obtener la siguiente matriz [] del algoritmo KPM

Hablemos brevemente sobre el principio. Primero, k se usa para almacenar el subíndice del prefijo. Primero, inicialice j=0 (j se usa para representar el subíndice de la cadena de patrón. Siempre compare cada bit de la cadena de patrón con el anterior uno. Si son iguales, registre qué posición la posición actual es la misma que la posición anterior. Principalmente queremos registrar la siguiente posición de la misma posición, que es la misma posición. Comenzar desde la misma posición para comparar es retroceder a la misma posición, por lo que aquí en t Cuando se establece [j]==t[k] , se requiere j+1, para comparar si la siguiente posición es la misma, k también es +1), la cadena de patrón comienza desde 0, k=-1, next[0]=-1 A la primera posición se le asigna un valor predeterminado de -1;

Aquí la cadena usa = "abab"

El primer bucle:

Determine si k es igual a -1, si es así, tanto j como k son +1,

En este momento, j=1, k=0, next[1]=0, es decir, la posición de retroceso de la segunda posición (subíndice 1) sigue siendo 0, porque la longitud máxima del prefijo debe ser menor que la longitud de la posición actual;

Segundo ciclo:

j=1, k=0, next[1]=0; k no es igual a -1, juez t[j]==t[k], t[1]==t[0], t[1] = "b", t[0] = "a", diferente

Ejecutar más:

k=siguiente[0]=-1

Tercer ciclo:

k==-1

Tanto j como k son +1, j=2, k=0, next[2]=0

Cuarto ciclo:

k no es igual a -1, juzgando t[2]==t[0], t[2]=“a”=t[0]=“a”, establecido

Tanto j como k son +1, j=3, k=1, next[3]=1

En este momento next=[-1,0,0,1], next[3]=1 significa que cuando ocurre una discrepancia en next[3], es decir, cuando el subíndice de la cadena de patrón es 3, es " b ", lo que indica que el aba anterior Todos coinciden con la cadena de destino, por lo que la cadena aba frente a la posición no coincidente de la cadena de patrones debe ser igual a los primeros 3 valores frente a la posición no coincidente de la cadena de destino, que es, aba, entonces en este momento, solo necesita retroceder a la posición 1 de la cadena de patrón, es decir, la b de la cadena de patrón, la cadena de patrón b está precedida por a, y la a anterior de la cadena de destino es satisfecho.

Quinto ciclo:

k todavía no es igual a -1, es decir, comparar los dos números después de la posición anterior y luego compararlos. En pocas palabras, saque cada elemento y compárelo con el primero. Si hay uno igual, luego compare el el siguiente con el segundo los artículos son iguales.

el código se muestra a continuación:

def GetNext(t, next):
    j, k = 0, -1
    next[0] = -1
    while j < len(t) - 1:
        if k == -1 or t[j] == t[k]:  # 如果k==-1 或者 开始位置和结尾位置有相同的元素
            j, k = j + 1, k + 1  # j和k都加1,当前位匹配,则从下一个位置开始匹配,所以k+1;j再进行取下一位判断是否也是匹配,所以也要+1
            next[j] = k  # 当前位置要取k项
        else:#如果不相等,再把k置-1,下一次循环再进行+1操作,j这个位置再存入0,表示无匹配项
            k = next[k]
    return next

2. Función KMP

El principio es el mismo que el algoritmo BF, la única diferencia es que cuando la cadena de patrón no coincide con la cadena de destino, la cadena de patrón no se retrocede directamente, pero la posición que se retrotraerá se consulta de acuerdo con la siguiente tabla [] de la cadena de patrón, directamente Retrocediendo a la posición especificada de la cadena de patrón, el núcleo del algoritmo KMP está aquí, pero este método generalmente solo es efectivo cuando hay los mismos elementos en el prefijo y el sufijo, es decir, el mismo parte es la misma y ya no se comparará. La comparación comienza desde la siguiente posición del mismo elemento, por lo que la parte más complicada del algoritmo KMP es encontrar la siguiente tabla [], para averiguar si cada posición de la la cadena de patrón tiene el mismo prefijo, si es así, marque la misma posición, la próxima vez que Retroceda no necesite retroceder a la posición 0, puede comenzar desde una posición diferente.

def KMP(s, t):
    next = [0] * len(t)
    next = GetNext(t, next)
    print(next)
    i, j = 0, 0
    while i < len(s) and j < len(t):
        if j == -1 or s[i] == t[j]:
            i, j = i + 1, j + 1
        else:
            j = next[j]
    if j >= len(t):
        return i - len(t)
    else:
        return -1

Código completo:

def GetNext(t, next):
    j, k = 0, -1
    next[0] = -1
    while j < len(t) - 1:
        if k == -1 or t[j] == t[k]:  # 如果k==-1 或者 开始位置和结尾位置有相同的元素
            j, k = j + 1, k + 1  # j和k都加1,当前位匹配,则从下一个位置开始匹配,所以k+1;j再进行取下一位判断是否也是匹配,所以也要+1
            next[j] = k  # 当前位置要取k项
        else:#如果不相等,再把k置-1,下一次循环再进行+1操作,j这个位置再存入0,表示无匹配项
            k = next[k]
    return next


def KMP(s, t):
    next = [0] * len(t)
    next = GetNext(t, next)
    print(next)
    i, j = 0, 0
    while i < len(s) and j < len(t):
        if j == -1 or s[i] == t[j]:
            i, j = i + 1, j + 1
        else:
            j = next[j]
    if j >= len(t):
        return i - len(t)
    else:
        return -1


if __name__ == '__main__':
    re = KMP('asdfghjsssaaasdfaaaabababcdabd', "ababaaaababaa")
    print(re)

resultado:

 

Supongo que te gusta

Origin blog.csdn.net/baidu_39105563/article/details/121754173
Recomendado
Clasificación