simple_huffman 0.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/lib/huffman.rb +95 -0
- metadata +58 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 5255ece9e12754b57eb4438695d3322956a72992
|
4
|
+
data.tar.gz: e571960c4429e5070e022ce8c07ca4c147dd1836
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 4c2d86be3525cdc7b2ec1e1e12287f1370ab6323705e70b80155cc9ab56f58e7baa4f44f45b10b51b242eb2cea8e7f64d4fb07a3bd2b951e9a5cb55afd16c8de
|
7
|
+
data.tar.gz: c35a6e624273c8be709c06f19fc3b981ac73e8bf485072f3b43a4c55a0a1c2604eadbc2cc660fa625cbccd90a5a84eb50806e5e9da199b6a2c3c74f6148c922b
|
data/lib/huffman.rb
ADDED
@@ -0,0 +1,95 @@
|
|
1
|
+
class Node
|
2
|
+
attr_accessor :value, :weight, :left, :right, :order
|
3
|
+
def initialize(value, weight, order=0, left=nil, right=nil)
|
4
|
+
@value = value
|
5
|
+
@weight = weight
|
6
|
+
@left = left
|
7
|
+
@right = right
|
8
|
+
@order = order #actuality of the node
|
9
|
+
end
|
10
|
+
|
11
|
+
def traverse(code, hash)
|
12
|
+
if leaf?
|
13
|
+
hash[@value] = code
|
14
|
+
else
|
15
|
+
@left.traverse(code + '1', hash)
|
16
|
+
@right.traverse(code + '0', hash)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
#the sorting order should be defined by weight and order of the internal node
|
21
|
+
#for obtaining Huffman code with minimum variance the most recent internal node should be later in the list
|
22
|
+
def <=>(other)
|
23
|
+
if @weight < other.weight
|
24
|
+
-1
|
25
|
+
elsif @weight > other.weight
|
26
|
+
1
|
27
|
+
else
|
28
|
+
if @order < other.order
|
29
|
+
return -1
|
30
|
+
elsif @order > other.order
|
31
|
+
return 1
|
32
|
+
end
|
33
|
+
0
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def leaf?
|
38
|
+
@left.nil? && @right.nil?
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
class Huffman
|
43
|
+
# frequencies should be a hash containing the occuring letters of the text and their corresponding frequency
|
44
|
+
# i.e. {'a' => 5, 'b' => 3}
|
45
|
+
def self.encode(text, frequencies=nil)
|
46
|
+
frequencies = get_frequencies(text) unless frequencies
|
47
|
+
tree = build_tree(frequencies)
|
48
|
+
code_table = {}
|
49
|
+
frequencies.size > 1 ? tree.traverse('', code_table) : code_table = {frequencies.keys[0] => '0'}
|
50
|
+
{encoded_text: text.chars.map{|char| code_table[char]}.join, code_table: code_table}
|
51
|
+
end
|
52
|
+
|
53
|
+
def self.decode(encoded_text, code_table)
|
54
|
+
text = []
|
55
|
+
code_table = code_table.invert
|
56
|
+
previous = ''
|
57
|
+
encoded_text.each_char do |char|
|
58
|
+
if code_table[previous + char]
|
59
|
+
text << code_table[previous + char]
|
60
|
+
previous = ''
|
61
|
+
else
|
62
|
+
previous += char
|
63
|
+
end
|
64
|
+
end
|
65
|
+
text.join
|
66
|
+
end
|
67
|
+
|
68
|
+
private
|
69
|
+
def self.get_frequencies(text)
|
70
|
+
frequencies = Hash.new(0)
|
71
|
+
text.each_char do |char|
|
72
|
+
frequencies[char] += 1
|
73
|
+
end
|
74
|
+
frequencies
|
75
|
+
end
|
76
|
+
|
77
|
+
def self.build_tree(frequencies)
|
78
|
+
nodes = []
|
79
|
+
frequencies.each_pair do |letter, frequency|
|
80
|
+
nodes << Node.new(letter, frequency)
|
81
|
+
end
|
82
|
+
|
83
|
+
order = 1
|
84
|
+
while nodes.length > 1 do
|
85
|
+
nodes.sort!
|
86
|
+
left = nodes.shift
|
87
|
+
right = nodes.shift
|
88
|
+
combined = Node.new('', left.weight + right.weight, order, left, right)
|
89
|
+
nodes << combined
|
90
|
+
order += 1
|
91
|
+
end
|
92
|
+
nodes.shift
|
93
|
+
end
|
94
|
+
|
95
|
+
end
|
metadata
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: simple_huffman
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Jiayi Zheng
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-11-03 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rspec
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
description: A simple implementation of huffman algorithm
|
28
|
+
email: ''
|
29
|
+
executables: []
|
30
|
+
extensions: []
|
31
|
+
extra_rdoc_files: []
|
32
|
+
files:
|
33
|
+
- lib/huffman.rb
|
34
|
+
homepage: https://github.com/thebluber
|
35
|
+
licenses:
|
36
|
+
- MIT
|
37
|
+
metadata: {}
|
38
|
+
post_install_message:
|
39
|
+
rdoc_options: []
|
40
|
+
require_paths:
|
41
|
+
- lib
|
42
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - ">="
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '0'
|
47
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
48
|
+
requirements:
|
49
|
+
- - ">="
|
50
|
+
- !ruby/object:Gem::Version
|
51
|
+
version: '0'
|
52
|
+
requirements: []
|
53
|
+
rubyforge_project:
|
54
|
+
rubygems_version: 2.2.0
|
55
|
+
signing_key:
|
56
|
+
specification_version: 4
|
57
|
+
summary: Huffman encoder/decoder
|
58
|
+
test_files: []
|