Guest User

Untitled

a guest
Dec 16th, 2018
86
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.17 KB | None | 0 0
  1. class TreeNode:
  2. def __init__(self, key, value, left_child=None, right_child=None, parent=None):
  3. self.key = key
  4. self.value = value
  5. self.left_child = left_child
  6. self.right_child = right_child
  7. self.parent = parent
  8.  
  9. def has_left_сhild(self):
  10. return self.left_child != None
  11.  
  12. def has_right_child(self):
  13. return self.right_child != None
  14.  
  15. from binary_tree import TreeNode
  16.  
  17. def two_minimal_numbers_array(array):
  18. first_min = second_min = None
  19. maximum = max(array)
  20.  
  21. # Первое минимальное значение
  22. for index, number in enumerate(array):
  23. if number <= maximum:
  24. maximum = number
  25. first_min = (number, index)
  26.  
  27. maximum = max(array)
  28. # Второе минимальное значение, пропуская первое найденное
  29. for index, number in enumerate(array):
  30. if index != first_min[1]:
  31. if number <= maximum:
  32. maximum = number
  33. second_min = (number, index)
  34.  
  35. # Возвращаем кортеж вида ((m1, i1), (m2, i2)), где mn - n-ое минимальное значение, in - его индекс
  36. return first_min, second_min
  37.  
  38. def create_bin_codes(main_node, bin_codes, code):
  39. if main_node.has_left_сhild():
  40. # Идем влево - к символу добавляется 0
  41. code += "0"
  42. # Если левый ребенок - символ, то добавляем его и его код в bin_codes
  43. if isinstance(main_node.left_child, str):
  44. bin_codes[main_node.left_child] = code
  45. # Идем обратно - убираем последнюю цифру code
  46. code = code[:-1]
  47. # Если нет - рекурсивно вызываем функцию с новым main_node
  48. else:
  49. create_bin_codes(main_node.left_child, bin_codes, code)
  50. # Идем обратно - убираем последнюю цифру code
  51. code = code[:-1]
  52. if main_node.has_right_child():
  53. # Идем вправо - к символу добавляется 1
  54. code += "1"
  55. # Если правый ребенок - символ, то добавляем его и его код в bin_codes
  56. if isinstance(main_node.right_child, str):
  57. bin_codes[main_node.right_child] = code
  58. # Идем обратно - убираем последнюю цифру code
  59. code = code[:-1]
  60. # Если нет - рекурсивно вызываем функцию с новым main_node
  61. else:
  62. create_bin_codes(main_node.right_child, bin_codes, code)
  63. # Идем обратно - убираем последнюю цифру code
  64. code = code[:-1]
  65.  
  66. # Тестовая строка
  67. source = "АААААААААААААААБББББББВВВВВВГГГГГГДДДДД"
  68. # Словарь частот
  69. letters = {}
  70. # Отдельный список с частотой каждого символа
  71. frequency = []
  72. # Он нужен, так как в дальнейшем в словаре будут появляться значения
  73. # класса TreeNode, которые не могут сравниваться с числами
  74.  
  75. # Заполнение словаря частот
  76. for i in source:
  77. if not letters.get(i):
  78. letters[i] = 0
  79. letters[i] = letters[i] + 1
  80.  
  81. # Заполнение списка частот
  82. for i in letters:
  83. frequency.append(letters[i])
  84.  
  85. # Проходимся по списку, оставляя в итоге 1 элемент
  86. for i in range(len(letters)-1):
  87. # Возвращает кортеж вида ((m1, i1), (m2, i2)), где mn - n-ое минимальное значение, in - его индекс
  88. minimals = two_minimal_numbers_array(frequency)
  89.  
  90. # Ключ первого минимального значения
  91. key_first = list(letters.keys())[minimals[0][1]]
  92. # Ключ второго минимального значения
  93. key_second = list(letters.keys())[minimals[1][1]]
  94. # Для того, чтобы вставлять в value каждого TreeNode
  95. node_key = key_first + key_second
  96.  
  97. # Удаляем старые значения
  98. frequency.remove(minimals[0][0])
  99. frequency.remove(minimals[1][0])
  100. # Складываем значения и вставляем их на последнее место
  101. frequency.append(minimals[0][0] + minimals[1][0])
  102.  
  103. # Здесь выполняется проверка, чтобы в потомках TreeNode записывались не сами строки,
  104. # длина которых > 1, а узлы, у которых value = этим строкам
  105. if len(key_first) > 1 and len(key_second) > 1:
  106. letters[node_key] = TreeNode(0, node_key, letters[key_first], letters[key_second])
  107. elif len(key_first) > 1:
  108. letters[node_key] = TreeNode(0, node_key, letters[key_first], key_second)
  109. elif len(key_second) > 1:
  110. letters[node_key] = TreeNode(0, node_key, key_first, letters[key_second])
  111. else:
  112. letters[node_key] = TreeNode(0, node_key, key_first, key_second)
  113.  
  114. # Удаляем использованные элементы
  115. letters.pop(key_first)
  116. letters.pop(key_second)
  117.  
  118. # Берем значение первого (и единственного) элемента
  119. final_tree = letters[next(iter(letters))]
  120.  
  121. del frequency, letters
  122.  
  123. # bin_codes - словарь, который содержит бинарный код для каждого символа
  124. bin_codes = {}
  125. # Переменная, содержащая бинарный код, в зависимости от движения по дереву
  126. code = ""
  127.  
  128. # Вызываем функцию обхода дерева с присвоением бинарного кода символам
  129. create_bin_codes(final_tree, bin_codes, code)
  130.  
  131. del final_tree, code
  132.  
  133. # Кодирование строки
  134. final_bin_string = ""
  135. for letter in source:
  136. final_bin_string += bin_codes[letter]
  137.  
  138. self.left_child is not None
  139.  
  140. class TreeNode:
  141. __slots__ = ('key', 'value', 'left_child', 'right_child', 'parent')
Add Comment
Please, Sign In to add comment