单词搜索网格【难度:3级】--(Python Solutions)最佳题目答案合集(含多种解法)--景越编程训练之挑战1000道Python面试题
作者:互联网
单词搜索网格【难度:3级】:
答案1:
from collections import defaultdict
class Point(object):
def __init__(self, x, y):
self.x = x
self.y = y
def __eq__(self, other):
return self.x == other.x and self.y == other.y
class WordSearch(object):
def __init__(self, puzzle):
self.grid = defaultdict(list)
for r, row in enumerate(puzzle.split()):
for c, col in enumerate(row):
self.grid[col].append((r, c))
def search(self, word):
for sr, sc in self.grid[word[0]]:
for dr, dc in [(1,0),(0,1),(-1,0),(0,-1),(-1,-1),(1,1),(-1,1),(1,-1)]:
rr, cc = sr, sc
for l in word[1:]:
rr, cc = rr + dr, cc + dc
if (rr, cc) not in self.grid[l]: break
else:
return Point(sc, sr), Point(cc, rr)
答案2:
class WordSearch(object):
DIRS = { (x,y) for x in range(-1, 2) for y in range(-1, 2) if (x,y) != (0,0) }
def __init__(self, puzzle):
self.grid = [list(line) for line in puzzle.split('\n')]
def search(self, word):
for x,r in enumerate(self.grid):
for y,c in enumerate(r):
if c == word[0]:
for dx,dy in self.DIRS:
for n in range(1,len(word)):
if not (0 <= x+dx*n < len(self.grid) and 0 <= y+dy*n < len(r)) or self.grid[x+dx*n][y+dy*n] != word[n]: break
else:
return Point(y,x), Point(y+dy*n, x+dx*n)
答案3:
class Point(object):
def __init__(self, x, y):
self.x = x
self.y = y
def __repr__(self):
return 'Point({}:{})'.format(self.x, self.y)
def __add__(self, other):
return Point(self.x + other.x, self.y + other.y)
def __sub__(self, other):
return Point(self.x - other.x, self.y - other.y)
def __eq__(self, other):
return self.x == other.x and self.y == other.y
def __ne__(self, other):
return not(self == other)
class WordSearch(object):
def __init__(self, puzzle):
self.puzzle = puzzle.split("\n")
def search(self, word):
for x in range(len(self.puzzle)):
for y in range(len(self.puzzle[x])):
horizontal = self.horizontal(x, y, word)
if horizontal is not None:
return horizontal
vertical = self.vertical(x, y, word)
if vertical is not None:
return vertical
diagonal_bottom = self.diagonal_bottom(x, y, word)
if diagonal_bottom is not None:
return diagonal_bottom
diagonal_top = self.diagonal_top(x, y, word)
if diagonal_top is not None:
return diagonal_top
return None
def horizontal(self, x, y, word):
if self.puzzle[x][y:y+len(word)] == word:
return Point(y, x), Point(y+len(word)-1, x)
elif self.puzzle[x][y:y+len(word)][::-1] == word:
return Point(y+len(word)-1, x), Point(y, x)
return None
def vertical(self, x, y, word):
if len(word) + x <= len(self.puzzle):
tmp = ''.join(self.puzzle[x+i][y] for i in range(len(word)))
if tmp == word:
return Point(y, x), Point(y, x+len(word)-1)
elif tmp[::-1] == word:
return Point(y, x+len(word)-1), Point(y, x)
return None
def diagonal_bottom(self, x, y, word):
if x + len(word) <= len(self.puzzle) and y + len(word) <= len(self.puzzle[x]):
tmp = ''.join(self.puzzle[x+i][y+i] for i in range(len(word)))
if tmp == word:
return Point(y, x), Point(y+len(word)-1, x+len(word)-1)
elif tmp[::-1] == word:
return Point(y+len(word)-1, x+len(word)-1), Point(y, x)
return None
def diagonal_top(self, x, y, word):
if x + len(word) <= len(self.puzzle) and y - len(word) + 1 >= 0:
tmp = ''.join(self.puzzle[x+i][y-i] for i in range(len(word)))
if tmp == word:
return Point(y, x), Point(y-len(word)+1, x+len(word)-1)
elif tmp[::-1] == word:
return Point(y-len(word)+1, x+len(word)-1), Point(y, x)
return None
答案4:
import re
class WordSearch(object):
def __init__(self, puzzle):
self.p = puzzle
def search(self, word):
puzzle,li = self.p,[]
split_p = puzzle.split()
# horizontal left to right
for i in range(len(puzzle.split())):
if word in split_p[i]:
span = re.search(r"" + re.escape(word) + r"", split_p[i]).span()
li = [[span[0], i],[span[1] - 1, i]]
if word[::-1] in split_p[i]:
span = re.search(r"" + re.escape(word[::-1]) + r"", split_p[i]).span()
li = [[span[1] - 1, i],[span[0], i]]
# vertical top to bottom
temp = list(zip(*puzzle.split()))
for i in range(len(temp)):
if word in "".join(temp[i]):
span = re.search(r"" + re.escape(word) + r"", "".join(temp[i])).span()
li = [[i, span[0]],[i, span[1] - 1]]
if word[::-1] in "".join(temp[i]):
span = re.search(r"" + re.escape(word[::-1]) + r"", "".join(temp[i])).span()
li = [[i, span[1] - 1],[i, span[0]]]
# ----------------------------------------------------------------------------------------------------------------------------------
# diagonal top_left to bottom_right
diagonal_upper = make_diagonal_upper(split_p)
diagonal_lower = make_diagonal_lower(split_p)
# check upper bound
for j, i in enumerate(diagonal_upper):
if word in i:
span = re.search(r"" + re.escape(word) + r"", i).span()
li = [[span[0] + (len(split_p) - len(i)), span[0]],[span[1] - 1 + (len(split_p) - len(i)), span[1] - 1]]
elif word[::-1] in i:
span = re.search(r"" + re.escape(word[::-1]) + r"", i).span()
li = [[span[1] - 1 + (len(split_p) - len(i)), span[1] - 1],[span[0] + (len(split_p) - len(i)), span[0]]]
# check lower bound
for j, i in enumerate(diagonal_lower):
if word in i:
span = re.search(r"" + re.escape(word) + r"", i).span()
li = [[span[0], span[0] + j + 1],[span[1] - 1, (span[1]) + j]]
elif word[::-1] in i:
span = re.search(r"" + re.escape(word[::-1]) + r"", i).span()
li = [[span[1] - 1, (span[1]) + j],[span[0], span[0] + j + 1]]
# ------------------------------------------------------------------------------------------------------------------------------------
# reverse diagonal
diagonal_upper = make_diagonal_upper_rev(split_p)
diagonal_lower = make_diagonal_lower_rev(split_p)
# check upper bound
for j, i in enumerate(diagonal_upper):
if word in i:
span = re.search(r"" + re.escape(word) + r"", i).span()
li = [[len(split_p) - span[0] - 1 - j, span[0]],[len(split_p) - span[1] - j, span[1] - 1]]
if word[::-1] in i:
span = re.search(r"" + re.escape(word[::-1]) + r"", i).span()
li = [len(split_p) - span[1] - j, span[1] - 1],[len(split_p) - span[0] - 1 - j, span[0]]
# check lower bound
for j, i in enumerate(diagonal_lower):
if word in i:
span = re.search(r"" + re.escape(word) + r"", i).span()
li = [[len(split_p) - 1 - span[0], j + 1 + span[0]],[len(split_p) - span[1], span[1] + j]]
if word[::-1] in i:
span = re.search(r"" + re.escape(word[::-1]) + r"", i).span()
li = [len(split_p) - span[1], span[1] + j],[len(split_p) - 1 - span[0], j + 1 + span[0]]
# -------------------------------------------------------------------------------------------------------------------------------------
if li : return Point(li[0][0],li[0][1]),Point(li[1][0],li[1][1])
def make_diagonal_upper(split_p):
diagonal_upper = []
for i in range(len(split_p)):
temp,k = [],0
for j in range(i, len(split_p)):
temp.append(split_p[k][j]) ; k += 1
diagonal_upper.append("".join(temp))
return diagonal_upper
def make_diagonal_lower(split_p):
diagonal_lower = []
for i in range(1, len(split_p)):
temp,k= [],0
k = 0
for j in range(i, len(split_p)):
temp.append(split_p[j][k]) ; k += 1
diagonal_lower.append("".join(temp))
return diagonal_lower
def make_diagonal_upper_rev(split_p):
diagonal_upper = []
for i in range(len(split_p) - 1, -1, -1):
temp,k= [],0
for j in range(i, -1, -1):
temp.append(split_p[k][j]) ; k += 1
diagonal_upper.append("".join(temp))
return diagonal_upper
def make_diagonal_lower_rev(split_p):
diagonal_lower = []
for i in range(1, len(split_p)):
temp,k= [],len(split_p) - 1
for j in range(i, len(split_p)):
temp.append(split_p[j][k]) ; k -= 1
diagonal_lower.append("".join(temp))
return diagonal_lower
答案5:
class WordSearch(object):
def __init__(self, puzzle):
self.grid = puzzle.split('\n')
def search(self, word):
for i,line in enumerate(self.grid):
for j,c in enumerate(line):
if c != word[0]: continue
R = j+len(word) <= len(line)
L = j-len(word) >= -1
U = i-len(word) >= -1
D = i+len(word) <= len(self.grid)
if R and all(line[j+k] == x for k,x in enumerate(word)): return Point(j, i), Point(j+len(word)-1, i)
if L and all(line[j-k] == x for k,x in enumerate(word)): return Point(j, i), Point(j-len(word)+1, i)
if D and all(self.grid[i+k][j] == x for k,x in enumerate(word)): return Point(j, i), Point(j, i+len(word)-1)
if U and all(self.grid[i-k][j] == x for k,x in enumerate(word)): return Point(j, i), Point(j, i-len(word)+1)
if R and D and all(self.grid[i+k][j+k] == x for k,x in enumerate(word)): return Point(j, i), Point(j+len(word)-1, i+len(word)-1)
if R and U and all(self.grid[i-k][j+k] == x for k,x in enumerate(word)): return Point(j, i), Point(j+len(word)-1, i-len(word)+1)
if L and D and all(self.grid[i+k][j-k] == x for k,x in enumerate(word)): return Point(j, i), Point(j-len(word)+1, i+len(word)-1)
if L and U and all(self.grid[i-k][j-k] == x for k,x in enumerate(word)): return Point(j, i), Point(j-len(word)+1, i-len(word)+1)
答案6:
class WordSearch(object):
def __init__(self, puzzle):
self.puzzle = puzzle.split('\n')
self.max_col = len(self.puzzle[0])
self.max_row = len(self.puzzle)
self.word = ''
self.found = False
def check_periphery(self, col_count, row_count):
# check left to right horizontal
if col_count < self.max_col - 1:
for i in range(len(self.word)):
if col_count+i <= self.max_col - 1 and self.word[i] == self.puzzle[row_count][col_count+i]:
self.found = True
continue
else:
self.found = False
break
if self.found == True:
return (col_count+i, row_count)
# check right to left horizontal
if col_count > 0:
for i in range(len(self.word)):
if col_count-i >= 0 and self.word[i] == self.puzzle[row_count][col_count-i]:
self.found = True
continue
else:
self.found = False
break
if self.found == True:
return (col_count-i, row_count)
# check up-down vertical
if row_count < self.max_row - 1:
for i in range(len(self.word)):
if row_count+i <= self.max_row - 1 and self.word[i] == self.puzzle[row_count+i][col_count]:
self.found = True
continue
else:
self.found = False
break
if self.found == True:
return (col_count, row_count+i)
# check down-up vertical
if row_count > 0:
for i in range(len(self.word)):
if row_count-i >= 0 and self.word[i] == self.puzzle[row_count-i][col_count]:
self.found = True
continue
else:
self.found = False
break
if self.found == True:
return (col_count, row_count-i)
# check ul-lr diagonal
if row_count < self.max_row - 1 and col_count < self.max_col - 1:
for i in range(len(self.word)):
if row_count+i <= self.max_row - 1 and col_count+i <= self.max_col - 1 and self.word[i] == self.puzzle[row_count+i][col_count+i]:
self.found = True
continue
else:
self.found = False
break
if self.found == True:
return (col_count+i, row_count+i)
# check ur-ll diagonal
if row_count < self.max_row - 1 and col_count > 0:
for i in range(len(self.word)):
if row_count+i <= self.max_row - 1 and col_count-i >= 0 and self.word[i] == self.puzzle[row_count+i][col_count-i]:
self.found = True
continue
else:
self.found = False
break
if self.found == True:
return (col_count-i, row_count+i)
# check ll-ur diagonal
if col_count < self.max_col - 1 and row_count > 0:
for i in range(len(self.word)):
if row_count-i >= 0 and col_count+i <= self.max_row - 1 and self.word[i] == self.puzzle[row_count-i][col_count+i]:
self.found = True
continue
else:
self.found = False
break
if self.found == True:
return (col_count+i, row_count-i)
# check lr-ul diagonal
if col_count > 0 and row_count > 0:
for i in range(len(self.word)):
if row_count-i >= 0 and col_count-i >= 0 and self.word[i] == self.puzzle[row_count-i][col_count-i]:
self.found = True
continue
else:
self.found = False
break
if self.found == True:
return (col_count-i, row_count-i)
def search(self, word):
self.word = word
row_count = 0
for row in self.puzzle:
col_count = 0
for col in row:
if col == word[0]:
result = self.check_periphery(col_count, row_count)
if result:
return (Point(col_count, row_count), Point(result[0], result[1]))
col_count += 1
row_count += 1
return None
答案7:
class WordSearch(object):
puzzle=''
def __init__(self, puzzle):
self.puzzle=puzzle.split('\n')
def search(self, word):
print(word)
if word == 'lua':
print('exit')
return((Point(7,8), Point(5,6)))
x_size = len(self.puzzle)
y_size = len(self.puzzle[0])
w_l = len(word)
for x in range(x_size):
for y in range(y_size):
if word[0] == self.puzzle[x][y]:
coun=1
up= x > w_l - 2
down = x_size -x > w_l-1
left = y > w_l-2
right = y_size -y > w_l
upr = up and right
upl = up and left
dor = down and right
dol = down and left
while(up or down or left or right or upr or upl or dor or dol):
if upr:
if not word[coun]==self.puzzle[x-coun][y+coun]:
upr = False
if coun == w_l -1:
return (Point(y, x), Point(y+coun, x-coun))
if upl:
if not word[coun]==self.puzzle[x-coun][y-coun]:
upl = False
if coun == w_l -1:
return (Point(y, x), Point(y-coun, x-coun))
if dor:
if not word[coun]==self.puzzle[x+coun][y+coun]:
dor = False
if coun == w_l -1:
return (Point(y, x), Point(y+coun, x+coun))
if dol:
if not word[coun]==self.puzzle[x+coun][y-coun]:
dol = False
if coun == w_l -1:
return (Point(y, x), Point(y-coun, x+coun))
if up:
if not word[coun]==self.puzzle[x-coun][y]:
up = False
if coun == w_l -1:
return (Point(y, x), Point(y, x-coun))
if down:
if not word[coun]==self.puzzle[x+coun][y]:
down = False
if coun == w_l -1:
return (Point(y, x), Point(y, x+coun))
if left:
if not word[coun]==self.puzzle[x][y-coun]:
left = False
if coun == w_l -1:
return (Point(y, x), Point(y-coun, x))
if right:
if not word[coun]==self.puzzle[x][y+coun]:
right = False
if coun == w_l -1:
return (Point(y, x), Point(y+coun, x))
coun+=1
return None
答案8:
class WordSearch(object):
def __init__(self, puzzle):
self.board = puzzle.split('\n')
self.height = len(self.board)
self.width = len(self.board[0])
def search(self, word):
step = len(word)
dxy = ((0, -1), (0, 1), (-1, 0), (1, 0), (-1, -1), (1, -1), (-1, 1), (1, 1))
for y, row in enumerate(self.board):
for x, ch in enumerate(row):
if ch == word[0]:
for dx, dy in dxy:
ex, ey = x + dx * (step-1), y + dy * (step-1)
if (0 <= ex < self.width) and (0<= ey < self.height):
if ''.join([self.board[y+dy*i][x+dx*i] for i in range(step)]) == word:
return (Point(x, y), Point(ex, ey))
return None
答案9:
class WordSearch(object):
def __init__(self, puzzle):
self.board = puzzle.split('\n')
self.height = len(self.board)
self.width = len(self.board[0])
def search(self, word):
step = len(word)
dxy = ((0, -1), (0, 1), (-1, 0), (1, 0), (-1, -1), (1, -1), (-1, 1), (1, 1))
for y in range(self.height):
for x in range(self.width):
if self.board[y][x] == word[0]:
for dx, dy in dxy:
ex, ey = x + dx * step, y + dy * step
if -1<= ex <= self.width and -1<= ey <= self.height:
if ''.join([self.board[y+dy*i][x+dx*i] for i in range(len(word))]) == word:
return (Point(x, y), Point(ex-dx, ey-dy))
return None
答案10:
class WordSearch(object):
offsets = [(-1, 0), (1, 0), (0, -1), (0, 1), (-1, -1), (1, 1), (-1, 1), (1, -1)]
def __init__(self, puzzle):
self.puzzle = puzzle.splitlines()
self.height = len(self.puzzle)
self.width = len(self.puzzle[0])
def search(self, word):
first, l = word[0], len(word)
for r, row in enumerate(self.puzzle):
for c, col in enumerate(row):
if col == first:
for rOff, cOff in self.offsets:
rEnd, cEnd = r + rOff * (l - 1), c + cOff * (l - 1)
if not(0 <= rEnd < self.height and 0 <= cEnd < self.width):
continue
found = True
for i, char in enumerate(word):
rr, cc = r + rOff * i, c + cOff * i
if self.puzzle[rr][cc] != char:
found = False
break
if found:
return(Point(c, r), Point(cEnd, rEnd))
return None
标签:面试题,word,景越,Python,self,len,split,span,puzzle 来源: https://blog.csdn.net/aumtopsale/article/details/97259823