#算法11;判斷一個二維矩陣中是否有一個字符串,它通過一個每個格點有且僅一次,不能重複通過
#這裏定義的是搜索的四個方向
# x + 0, y - 1 ->向"上"搜索
# x + 0, y + 1 ->向"下"搜索
# x - 1, y + 0 ->向"左"搜索
# x + 1, y + 0 ->向"右"搜索
next_ = [[0,-1],[0,1],[-1,0],[1,0]]
#這個函數的功能就是將字符轉換爲矩陣形式
#轉換函數所用爲:buildMatrix
#然後建立一個同樣大小的標記矩陣:marked
#通過在標記矩陣中記錄搜索過的地方來對每個矩陣點進行搜索(上下左右四個方向)
#而搜索的方法就是"回溯法"?->所用函數名稱爲:backtracking
#“回溯法”在搜索的時候從矩陣左上角點開始搜索:然後方別搜索這一點的四個方向
#從四個方向又是四個"搜索點",每一個"搜索點"開始分別再向四周(上下左右)搜索
#直到"搜索點"處的字符與目標字符串中對應位置字符不同(失敗),或者搜索點不存在(位於矩陣索引值範圍外->失敗)
#或者達到搜索字符串長度值(成功),或者搜索點處已經被搜索過(標記二維列表中對應點處被標記過->失敗)
def hasPath(array,rows,cols,strs):
if rows == 0 or cols == 0:
return False
hereRows = rows
hereCols = cols
marked = [[0]*hereCols for row in range(hereRows)]
#這裏打印出我們初始標記二維列表
matrix = buildMatrix(array,rows,cols)
print("Our searching result is:")
for i in range(rows):
for j in range(cols):
if backtracking(matrix,strs,marked,0,i,j):
return True
return False
def buildMatrix(array,rows,cols):
idx = 0
matrix = [[None]*cols for row in range(rows)]
for r in range(rows):
for c in range(cols):
matrix[r][c] = array[idx]
idx += 1
#這裏打印出我們構造好的矩陣
print(matrix)
return matrix
#回溯搜索方法:它和遞歸有相似的地方就是"一直調用自身"
#不同的地方就是:它在搜索求解不成功的情況下,會"修復"它所走過的出發點
#在記錄矩陣中除去它所留下的痕跡(這是在該點四周一個都不成功的情況下)
#只要某點出發,四個方向至少有一個方向有成功搜索的情況,那麼該點仍然不會被除去搜索痕跡
def backtracking(matrix,strs,marked,pathLen,r,c):
if pathLen == len(strs):
return True
if r<0 or r>=rows or c<0 or c>=cols or matrix[r][c]!=strs[pathLen] or marked[r][c]:
return False
marked[r][c] = 1
for n in next_:
if backtracking(matrix,strs,marked,pathLen+1,r+n[0],c+n[1]):
return True
marked[r][c] = 0
return False
#這裏設置矩陣行列數
rows = 3
cols = 4
#這裏定義矩陣中元素->搜索二維矩陣內值(即字符串搜索範圍)
array = [e for e in "abtgcfcsjdeh"]
#print(array)->輸出驗證是否表達正確
#這裏定義被搜索字符串值
strs = "bfce"
print("Our searching target string is:")
print(strs)
print("Our built matrix:")
#搜索第一個字符串"bcfe"是否成功呢?
print(hasPath(array,rows,cols,strs))
print('\n')
strs2 = "acbf"
print("Our searching target string2 is:")
print(strs2)
print("Our built matrix:")
#搜索第二個字符串是否成功呢?
print(hasPath(array,rows,cols,strs2))