1.题目:
给定一个字母矩阵,找到矩阵中所有的单词。
1.1只能斜线连接字母
1.2可以斜线和直线连接字母,每个字母只能用一次
1.3可以斜线和直线连接字母,每个字母可以使用多次
2.解答:
这里只做第二题,第二题做出来,第一题和第三题都不在话下,代码如下:
-
import enchant
-
import time
-
d = enchant.Dict('en_US')
-
-
matrix = [
-
['H', 'T', 'Q', 'Z', 'A'],
-
['F', 'E', 'O', 'H', 'P'],
-
['O', 'M', 'L', 'M', 'B'],
-
['C', 'S', 'O', 'L', 'Q'],
-
['H', 'X', 'D', 'K', 'O']
-
]
-
-
# 1.设置搜索起点
-
# 2.每次深度加一进行搜索,然后判断
-
# 3.对搜索过的位置,要做标记,不能重复搜索
-
-
class SearchWords(object):
-
-
def __init__(self, matrix):
-
self.max_x = len(matrix[0])
-
self.max_y = len(matrix)
-
-
self.matrix = matrix
-
self.result = []
-
self.visited = set() # 是否已经搜索过
-
-
self.temp_list = [] # 存放需要下一步继续搜索的单词
-
-
def search_onestep(self, start_x, start_y, word, direct_x, direct_y):
-
# 做标记,表明这个点已经搜索过了
-
self.visited.add((start_x,start_y))
-
-
"""搜索,指定方向走一步"""
-
new_x = start_x + direct_x
-
new_y = start_y + direct_y
-
-
# 判断边界条件
-
if new_x >= self.max_x or new_y >= self.max_y or new_x < 0 or new_y < 0:
-
return
-
-
# 判断是否已经搜索过了
-
if (new_x,new_y) in self.visited:
-
return
-
# 新的字母
-
word = word + self.matrix[new_x][new_y]
-
-
# 判断是不是单词
-
if self.is_word(word):
-
print("这是一个单词",word)
-
self.result.append(word)
-
-
# 判断是不是单词开头
-
if self.is_words_head(word):
-
print("加入继续搜索列表中:",word)
-
self.temp_list.append(word)
-
-
return word,new_x,new_y
-
-
def is_word(self, word):
-
return d.check(word)
-
-
-
def search_eight_directions(self,start_x, start_y, word):
-
"""搜索八个方向"""
-
for x in range(-1,2):
-
for y in range(-1,2):
-
if x == 0 and y == 0:
-
continue
-
-
new_info = self.search_onestep(start_x, start_y, word, x, y)
-
if new_info:
-
print('新的坐标',new_info)
-
new_word,new_x,new_y = new_info
-
-
self.search_eight_directions(new_x, new_y, new_word)
-
-
def is_words_head(self,word):
-
"""判断当前字符串是不是一个单词的开头"""
-
for likely_word in d.suggest(word):
-
if likely_word.startswith(word):
-
return True
-
return False
-
-
-
def run(self):
-
"""启动函数"""
-
for x in range(self.max_x):
-
for y in range(self.max_y):
-
self.search_eight_directions(x, y,self.matrix[x][y])
-
self.visited = set()
-
# 去重
-
result = set(self.result)
-
print(result)
-
-
if __name__ == '__main__':
-
time1 = time.time()
-
s = SearchWords(matrix)
-
s.run()
-
time2 = time.time()
-
print("总共耗时:{}".format(time2-time1))
3.大致思路
- 设置搜索的起点,每一次搜索,深度增加1
- 对每次广度搜索都要做标记,避免重复使用字母
- 引入enchant模块,对字母串进行判断,包括是不是单词,以及是不是某个单词的开头
- 利用递归,每次深度加一搜索后,获取需要的参数,再次进行调用