pavel_777

trie

Mar 15th, 2022 (edited)
111
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 4.41 KB | None | 0 0
  1. """
  2. Дан текст T и набор строк. Надо определить, представим ли Т из этих строк.
  3. Строка s_i может встречаться в разбиении текста T произвольное число раз.
  4. Можно использовать не все строки для разбиения. Строки могут идти в любом порядке.
  5.  
  6. -- ПРИНЦИП РАБОТЫ --
  7. Сначала строим префиксное дерево по всем словам. После чтения слова сразу добавляем его в префиксное дерево.
  8. При этом помечаем вершины - концы слов (`end` = True)
  9.  
  10. Дальше с помощью динамического программирования пытаемся уложить слова в тексте.
  11. - Строка dp - это булевый массив равный длине текста.
  12. - True - означает, что текущее слово с учетом некоторого сочетания пройденных слов заканчивается
  13. на текущем индексе буквы `i`.
  14.  
  15. - Базовый случай.
  16. Базовый случай - это пустая строка.
  17. Для служебного индекса 0 мы записываем значение True
  18.  
  19. - Порядок вычисления:
  20. Мы обходим текст. Если перед текущим символов закончилось какое то слова, то мы ищем
  21. в префиксном дереве все слова, которые могут продолжить текст дальше и помечаем окончания (индекс текста)
  22. таких слов равными True
  23.  
  24. - Переход динамики:
  25. Переход происходит, если в текущем элементе True, что означает, что до текущего символа можно составить текст
  26. из какого-то сочетания слов словаря.
  27.  
  28. - Ответ хранится в последнем элементе:
  29. True - значит какое-то сочетание любых слов из словаря составило текст целиком.
  30.  
  31. -- СЛОЖНОСТЬ АЛГОРИТМА --
  32. Сложность создания префиксного дерева линейная и составляет O(n), где n - число всех букв во всех словах словаря.
  33. Потому что мы проходим каждое слово по буквам.
  34. Сложность поиска составляет в худшем случае O(s * n)
  35. Где s - длина текста.
  36. Мы проходим текст по букве и затем обходим в дереве подходящие слова.
  37.  
  38.  
  39. -- ПРИМЕРЫ ВВОДА И ВЫВОДА --
  40.  
  41. examiwillpasstheexam
  42. 5
  43. will
  44. pass
  45. the
  46. exam
  47. i
  48. = YES
  49.  
  50. abacaba
  51. 2
  52. abac
  53. caba
  54. = NO
  55.  
  56. abacaba
  57. 3
  58. abac
  59. caba
  60. aba
  61. = YES
  62.  
  63. bwvfbtrjqpbwvfbbwvbwbbwbbwvbwvf
  64. 4
  65. bwvf
  66. b
  67. bw
  68. bwv
  69. = NO
  70.  
  71.  
  72. """
  73. import sys
  74.  
  75.  
  76. class NodeTrie:
  77.     def __init__(self):
  78.         self.children = {}
  79.         self.end = False
  80.  
  81.     def add_node(self, ch):
  82.         self.children[ch] = NodeTrie()
  83.  
  84.  
  85. def add_word(trie, word):
  86.     cur_node = trie
  87.     for ch in word:
  88.         if ch not in cur_node.children:
  89.             cur_node.add_node(ch)
  90.         cur_node = cur_node.children[ch]
  91.     cur_node.end = True
  92.     return trie
  93.  
  94.  
  95. def find_words(trie, text, start):
  96.     cur_node = trie
  97.     arr_idx = []
  98.     for i in range(start, len(text)):
  99.         if text[i] in cur_node.children:
  100.             cur_node = cur_node.children[text[i]]
  101.             if cur_node.end:
  102.                 arr_idx.append(i + 1)
  103.         else:
  104.             break
  105.     return arr_idx
  106.  
  107.  
  108. def check_text(trie, text):
  109.     dp = [True] + [False] * len(text)
  110.     for i in range(len(dp)):
  111.         if dp[i]:
  112.             arr_idx = find_words(trie, text, i)
  113.             for idx in arr_idx:
  114.                 dp[idx] = True
  115.     return 'YES' if dp[-1] else 'NO'
  116.  
  117.  
  118. def main():
  119.     text = input().strip()
  120.     n = int(input())
  121.     trie = NodeTrie()
  122.     for i in range(n):
  123.         word = sys.stdin.readline().strip()
  124.         trie = add_word(trie, word)
  125.     print(check_text(trie, text))
  126.  
  127.  
  128. if __name__ == '__main__':
  129.     main()
  130.  
Add Comment
Please, Sign In to add comment