编程语言
首页 > 编程语言> > 单词搜索网格【难度:3级】--(Python Solutions)最佳题目答案合集(含多种解法)--景越编程训练之挑战1000道Python面试题

单词搜索网格【难度: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