動態規劃法求解最長公共子序列(加turtle可視化)

運行截圖:(字符是手動輸入的)
在這裏插入圖片描述
在這裏插入圖片描述
這個代碼調了我超級久 以至於不想寫分析

import turtle
n = 50  # 每行間隔,小格子邊長
x = -250 # x初始值
y = 200 # y初始值

# 最長公共子序列 初始化二維數組並完成c,flag賦值
def lcs(a, b):
    lena = len(a)
    lenb = len(b)
    c = [[0 for i in range(lenb + 1)] for j in range(lena + 1)] # 記錄公共字符
    flag = [[0 for i in range(lenb + 1)] for j in range(lena + 1)] # 存放公共字符的結果
    for i in range(lena):
        for j in range(lenb):
            if a[i] == b[j]:
                c[i + 1][j + 1] = c[i][j] + 1
                flag[i + 1][j + 1] = 'ok'
            elif c[i + 1][j] > c[i][j + 1]:
                c[i + 1][j + 1] = c[i + 1][j]
                flag[i + 1][j + 1] = 'left'
            else:
                c[i + 1][j + 1] = c[i][j + 1]
                flag[i + 1][j + 1] = 'up'
    return c, flag

def print_Lcs(flag,a,i,j):
    if i == 0 or j == 0:
        return
    if flag[i][j] == 'ok':
        print_Lcs(flag,a,i-1,j-1)
        print(a[i-1],end='')
    elif flag[i][j] == 'left':
        print_Lcs(flag,a,i,j-1)
    else:
        print_Lcs(flag,a,i-1,j)

# 繪圖 序列c的可視化輸出
def draw(length: float, fill_color: str, put):
    turtle.pendown()
    turtle.begin_fill()
    turtle.fillcolor(fill_color)
    for index in range(4):
        turtle.forward(length)
        turtle.left(90)
    turtle.fd(20)
    turtle.write(put,align = 'center',font = '13') # 輸出c[]的值
    turtle.end_fill()
    turtle.penup()

# 可視化輸出字符a,b
def print_strings(a,b):
    xx= x
    yy = y+n
    j,k = 0.5*n,0.5*n
    for i in a:
        j += n
        turtle.penup()
        turtle.goto(xx+j,yy)
        turtle.write(i,align = 'center',font = '18')
    for i in b:
        k += n
        turtle.penup()
        turtle.goto(xx-5,yy-k)
        turtle.write(i,align = 'center',font = '18')

# 繪圖 彙總
def draw_final():
    ii = 0 # ii,jj 用來記錄上次的公共值的行列號
    jj = 0
    turtle.speed(20)
    turtle.pensize(2)
    turtle.penup()
    for i in range(len(a)+1):
        for j in range(len(b)+1):
            turtle.goto(x + j * n, y - i * n)
            if flag[i][j] == 'ok' and i>ii and j>jj: # 當行列號都大於上次的行列號時才輸出粉色
                draw(n, "pink", str(c[i][j]))
                ii == i
                jj = j
            else:
                draw(n, "white",str(c[i][j]))
    turtle.done()

if __name__ == '__main__':
    a = input("請輸入字符串一:")
    b = input("請輸入字符串二:")
    print_strings(b,a)
    print("最長公共子序列爲:",end="")
    c,flag = lcs(a,b)
    print_Lcs(flag, a, len(a), len(b))
    draw_final()

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章