Advertisement
Guest User

Untitled

a guest
Jun 24th, 2019
70
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.87 KB | None | 0 0
  1. use crate::Node::*;
  2. use std::cmp::{Eq, Ord, Ordering, PartialEq, PartialOrd, Reverse};
  3. use std::collections::{BinaryHeap, BTreeMap};
  4. use std::convert::From;
  5.  
  6. #[derive(Debug, Clone)]
  7. enum Node {
  8. Leaf(usize, char),
  9. Branch(usize, Box<Node>, Box<Node>),
  10. }
  11.  
  12. impl Node {
  13. fn frequency(&self) -> usize {
  14. match self {
  15. Leaf(f, ..) => *f,
  16. Branch(f, ..) => *f,
  17. }
  18. }
  19.  
  20. fn merge(lhs: Node, rhs: Node) -> Node {
  21. match (lhs, rhs) {
  22. (Leaf(f1, c1), Leaf(f2, c2)) => {
  23. Branch(f1 + f2, Box::new(Leaf(f1, c1)), Box::new(Leaf(f2, c2)))
  24. }
  25. (Leaf(f1, c1), Branch(f2, l, r)) => {
  26. Branch(f1 + f2, Box::new(Leaf(f1, c1)), Box::new(Branch(f2, l, r)))
  27. }
  28. (Branch(f1, l, r), Leaf(f2, c2)) => {
  29. Branch(f1 + f2, Box::new(Branch(f1, l, r)), Box::new(Leaf(f2, c2)))
  30. }
  31. (Branch(f1, l1, r1), Branch(f2, l2, r2)) => Branch(
  32. f1 + f2,
  33. Box::new(Branch(f1, l1, r1)),
  34. Box::new(Branch(f2, l2, r2)),
  35. ),
  36. }
  37. }
  38.  
  39. fn build_code(self) -> BTreeMap<char, String> {
  40. let mut code = BTreeMap::new();
  41. let mut s = String::new();
  42. self.add_char(&mut s, &mut code, '0');
  43. code
  44. }
  45.  
  46. fn add_char(self, s: &mut String, code: &mut BTreeMap<char, String>, a: char) {
  47. s.push(a);
  48. match self {
  49. Leaf(_, c) => {
  50. code.insert(c, s.clone());
  51. }
  52. Branch(_, l, r) => {
  53. l.add_char(s, code, '0');
  54. r.add_char(s, code, '1');
  55. }
  56. }
  57. s.pop();
  58. }
  59. }
  60.  
  61. impl From<(char, usize)> for Node {
  62. fn from((c, count): (char, usize)) -> Node {
  63. Leaf(count, c)
  64. }
  65. }
  66.  
  67. impl PartialEq for Node {
  68. fn eq(&self, other: &Node) -> bool {
  69. self.frequency() == other.frequency()
  70. }
  71. }
  72.  
  73. impl Eq for Node {}
  74.  
  75. impl Ord for Node {
  76. fn cmp(&self, other: &Node) -> Ordering {
  77. Reverse(self.frequency()).cmp(&Reverse(other.frequency()))
  78. }
  79. }
  80.  
  81. impl PartialOrd for Node {
  82. fn partial_cmp(&self, other: &Node) -> Option<Ordering> {
  83. Some(Reverse(self.frequency()).cmp(&Reverse(other.frequency())))
  84. }
  85. }
  86.  
  87. fn build_queue(message: &str) -> BinaryHeap<Node> {
  88. let mut map = BTreeMap::new();
  89. for c in message.chars() {
  90. map.entry(c).and_modify(|count| *count += 1).or_insert(1);
  91. }
  92. map.into_iter().map(Node::from).collect()
  93. }
  94.  
  95. fn main() {
  96. let mut queue = build_queue(
  97. "the quick brown 🦊fox🦊 jumps over the sleazy 🐢dog🐢. 🦊🦊🐢🦊🦊"
  98. );
  99. while queue.len() > 1 {
  100. let lhs = queue.pop().unwrap();
  101. let rhs = queue.pop().unwrap();
  102. queue.push(Node::merge(lhs, rhs));
  103. }
  104. let huffman_tree = queue.pop().unwrap();
  105. let huffman_code = huffman_tree.build_code();
  106. dbg!(&huffman_code);
  107. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement