Исследование поиска по нескольким словам в сетке с помощью поиска в глубину (DFS)

Поиск нескольких слов в сетке — распространенная проблема в информатике, которую можно найти в текстовых головоломках, кроссвордах и обработке данных. В этой статье мы рассмотрим различные методы решения этой проблемы с помощью исследования поиска в глубину (DFS). Мы предоставим примеры кода на Python для иллюстрации каждого метода.

Метод 1: метод грубой силы
Метод грубой силы включает в себя исчерпывающий поиск в сетке каждого слова. Мы перебираем каждую ячейку сетки и выполняем исследование DFS, начиная с этой ячейки, в поисках текущего слова. Вот пример реализации:

def search_word(grid, word):
    rows, cols = len(grid), len(grid[0])
    for i in range(rows):
        for j in range(cols):
            if dfs(grid, word, i, j, 0):
                return True
    return False
def dfs(grid, word, i, j, k):
    rows, cols = len(grid), len(grid[0])
    if i < 0 or i >= rows or j < 0 or j >= cols or grid[i][j] != word[k]:
        return False
    if k == len(word) - 1:
        return True
    temp = grid[i][j]
    grid[i][j] = "#"  # Mark the current cell as visited
    found = dfs(grid, word, i + 1, j, k + 1) or dfs(grid, word, i - 1, j, k + 1) \
            or dfs(grid, word, i, j + 1, k + 1) or dfs(grid, word, i, j - 1, k + 1)
    grid[i][j] = temp  # Restore the original value
    return found
# Example usage
grid = [
    ['A', 'B', 'C', 'E'],
    ['S', 'F', 'C', 'S'],
    ['A', 'D', 'E', 'E']
]
word = "ABCCED"
print(search_word(grid, word))  # Output: True

Метод 2: подход на основе дерева
Вместо того, чтобы выполнять исследование DFS для каждого слова, мы можем оптимизировать процесс поиска, используя структуру данных дерева. Мы создаем дерево со всеми целевыми словами, а затем выполняем исследование DFS в сетке, сопоставляя префиксы с деревом. Вот пример реализации:

class TrieNode:
    def __init__(self):
        self.children = {}
        self.is_word = False
def build_trie(words):
    root = TrieNode()
    for word in words:
        node = root
        for char in word:
            if char not in node.children:
                node.children[char] = TrieNode()
            node = node.children[char]
        node.is_word = True
    return root
def search_word(grid, words):
    rows, cols = len(grid), len(grid[0])
    trie = build_trie(words)
    result = []
    for i in range(rows):
        for j in range(cols):
            dfs(grid, i, j, trie, "", result)
    return result
def dfs(grid, i, j, node, path, result):
    rows, cols = len(grid), len(grid[0])
    char = grid[i][j]
    if char not in node.children:
        return
    node = node.children[char]
    path += char
    if node.is_word:
        result.append(path)
        node.is_word = False  # Mark the word as visited
    grid[i][j] = "#"  # Mark the current cell as visited
    if i > 0:
        dfs(grid, i - 1, j, node, path, result)
    if i < rows - 1:
        dfs(grid, i + 1, j, node, path, result)
    if j > 0:
        dfs(grid, i, j - 1, node, path, result)
    if j < cols - 1:
        dfs(grid, i, j + 1, node, path, result)
    grid[i][j] = char  # Restore the original value
# Example usage
grid = [
    ['A', 'B', 'C', 'E'],
    ['S', 'F', 'C', 'S'],
    ['A', 'D', 'E', 'E']
]
words = ["ABCCED", "SEE", "ABCB"]
print(search_word(grid, words))  # Output: ['ABCCED', 'SEE']

В этой статье мы рассмотрели два метода поиска по нескольким словам в сетке с использованием исследования DFS. Подход грубой силы прост, но может быть неэффективен для больших сеток или большого количества слов. Подход на основе дерева обеспечивает оптимизированное решение за счет использования структуры данных дерева. Реализуя эти методы, вы можете эффективно искать по нескольким словам в сетке.

Не забудьте адаптировать примеры кода к вашему конкретному варианту использования и требованиям. Удачных поисков по сетке!