運行截圖:(字符是手動輸入的)
這個代碼調了我超級久 以至於不想寫分析
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()