proffreda

Application of Recursive Data: Tree Encoding

Apr 5th, 2016
177
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 3.19 KB | None | 0 0
  1.  
  2. class BinTree:
  3.     empty = ()
  4.  
  5.     def __init__(self, label, left=empty, right=empty):
  6.         self.label = label
  7.         self.left = left
  8.         self.right = right
  9.  
  10.     def __repr__(self):
  11.         if self.left == self.empty and self.right == self.empty:
  12.             return 'BinTree({})'.format(repr(self.label))
  13.         left = 'BinTree.empty' if self.left == self.empty else repr(self.left)
  14.         right = 'BinTree.empty' if self.right == self.empty else repr(self.right)
  15.         return 'BinTree({}, {}, {})'.format(repr(self.label), left, right)
  16.  
  17.     def is_leaf(self):
  18.         return self.left == self.right == BinTree.empty
  19.  
  20. # Sample decoding tree from lecture.
  21.  
  22. CODED_ALPHABET = {
  23.     "A": "1110",
  24.     "B": "101100",
  25.     "C": "01000",
  26.     "D": "11111",
  27.     "E": "011",
  28.     "F": "00110",
  29.     "G": "111100",
  30.     "H": "0101",
  31.     "I": "1100",
  32.     "J": "001011001",
  33.     "K": "0010111",
  34.     "L": "10111",
  35.     "M": "00111",
  36.     "N": "1010",  
  37.     "O": "1101",  
  38.     "P": "101101",
  39.     "Q": "001011010",
  40.     "R": "1000",  
  41.     "S": "1001",  
  42.     "T": "000",    
  43.     "U": "01001",  
  44.     "V": "001010",
  45.     "W": "111101",
  46.     "X": "001011011",
  47.     "Y": "00100",  
  48.     "Z": "001011000",
  49. }
  50.  
  51. def make_encoding_tree(coding_map):
  52.     """An encoding tree that implements CODING_MAP, a dictionary mapping
  53.    characters to strings of 0s and 1s with the prefix property"""
  54.     def add(c, code):
  55.         """Add C to result with encoding CODE."""
  56.         T = result
  57.         for v in code:
  58.             if v == '0':
  59.                 if T.left is BinTree.empty:
  60.                     T.left = BinTree(None, BinTree.empty, BinTree.empty)
  61.                 T = T.left
  62.             else:
  63.                 if T.right is BinTree.empty:
  64.                     T.right = BinTree(None, BinTree.empty, BinTree.empty)
  65.                 T = T.right
  66.         T.label = c
  67.  
  68.     result = BinTree(None, BinTree.empty, BinTree.empty)
  69.     for c, code in coding_map.items():
  70.         add(c, code)
  71.     return result
  72.  
  73. ENCODING = make_encoding_tree(CODED_ALPHABET)
  74.  
  75. def decode(msg, encoding):
  76.     """Decode MSG according ENCODING.
  77.    MSG is a string of '0' and '1' characters.
  78.    ENCODING is a prefix tree where leaf nodes contain the
  79.    characters encoded by the path to that leaf.
  80.    >>> decode(encode("THE CAT IN THE HAT", CODED_ALPHABET), ENCODING)
  81.    'THEXCATXINXTHEXHAT'
  82.    """
  83.     result = ""
  84.     k = 0
  85.     def decode1():
  86.         """Decode and return character starting at MSG[k], incrementing
  87.        k to the bit after that character's representation."""
  88.         nonlocal k
  89.         T = encoding
  90.         while T.label is None: # or while not T.is_leaf()
  91.             if msg[k] == '0':
  92.                 T = T.left
  93.             else:
  94.                 T = T.right
  95.             k += 1
  96.         return T.label
  97.  
  98.     while k < len(msg):
  99.         result += decode1()
  100.     return result
  101.  
  102. def encode(msg, coding_map, default="X"):
  103.     """Encode MSG using CODING_MAP, a dictionary mapping characters to
  104.    strings of 0's and 1's.  Any unrecognized characters are replaced by
  105.    DEFAULT, which must be in CODING_MAP."""
  106.     d = coding_map[default]
  107.     return ''.join(map(lambda x: coding_map.get(x, d), msg))
Advertisement
Add Comment
Please, Sign In to add comment