rambling-trie 0.1.0 → 0.2.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.
- data/lib/children_hash_deferer.rb +20 -0
- data/lib/rambling-trie.rb +2 -0
- data/lib/trie.rb +12 -1
- data/lib/trie_compressor.rb +26 -0
- data/lib/trie_node.rb +29 -26
- metadata +3 -1
@@ -0,0 +1,20 @@
|
|
1
|
+
module Rambling
|
2
|
+
module ChildrenHashDeferer
|
3
|
+
def [](key)
|
4
|
+
@children[key]
|
5
|
+
end
|
6
|
+
|
7
|
+
def []=(key, value)
|
8
|
+
@children[key] = value
|
9
|
+
end
|
10
|
+
|
11
|
+
def delete(key)
|
12
|
+
@children.delete(key)
|
13
|
+
end
|
14
|
+
|
15
|
+
def has_key?(key)
|
16
|
+
@children.has_key?(key)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
data/lib/rambling-trie.rb
CHANGED
@@ -1,4 +1,6 @@
|
|
1
1
|
require File.join(File.dirname(__FILE__), 'invalid_trie_operation.rb')
|
2
|
+
require File.join(File.dirname(__FILE__), 'children_hash_deferer.rb')
|
3
|
+
require File.join(File.dirname(__FILE__), 'trie_compressor.rb')
|
2
4
|
require File.join(File.dirname(__FILE__), 'trie_node.rb')
|
3
5
|
require File.join(File.dirname(__FILE__), 'trie.rb')
|
4
6
|
|
data/lib/trie.rb
CHANGED
@@ -7,10 +7,21 @@ module Rambling
|
|
7
7
|
add_all_nodes if filename
|
8
8
|
end
|
9
9
|
|
10
|
+
def compress!
|
11
|
+
@is_compressed = true
|
12
|
+
super
|
13
|
+
end
|
14
|
+
|
15
|
+
def compressed?
|
16
|
+
@is_compressed
|
17
|
+
end
|
18
|
+
|
10
19
|
private
|
11
20
|
def add_all_nodes
|
12
21
|
File.open(@filename) do |file|
|
13
|
-
|
22
|
+
while word = file.gets
|
23
|
+
add_branch_from(word.chomp)
|
24
|
+
end
|
14
25
|
end
|
15
26
|
end
|
16
27
|
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Rambling
|
2
|
+
module TrieCompressor
|
3
|
+
def compress!
|
4
|
+
if @children.size == 1 and not terminal?
|
5
|
+
transfer_ownership_from(@children.values.first)
|
6
|
+
compress!
|
7
|
+
end
|
8
|
+
|
9
|
+
@children.values.each { |node| node.compress! }
|
10
|
+
|
11
|
+
self
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def transfer_ownership_from(child)
|
17
|
+
@parent.delete(@letter) unless @parent.nil?
|
18
|
+
@letter = (@letter.to_s + child.letter.to_s).to_sym
|
19
|
+
@parent[@letter] = self unless @parent.nil?
|
20
|
+
|
21
|
+
@children = child.children
|
22
|
+
@is_terminal = child.terminal?
|
23
|
+
@children.values.each { |node| node.parent = self }
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
data/lib/trie_node.rb
CHANGED
@@ -1,21 +1,22 @@
|
|
1
1
|
module Rambling
|
2
2
|
class TrieNode
|
3
|
-
|
3
|
+
include ChildrenHashDeferer
|
4
|
+
include TrieCompressor
|
5
|
+
|
6
|
+
attr_reader :letter, :children, :parent
|
4
7
|
|
5
8
|
def initialize(word, parent = nil)
|
6
9
|
@letter = nil
|
7
|
-
@word = ''
|
8
10
|
@parent = parent
|
9
11
|
@is_terminal = false
|
10
12
|
@children = {}
|
11
13
|
|
12
14
|
unless word.nil?
|
13
|
-
|
15
|
+
letter = word.slice!(0)
|
16
|
+
@letter = letter.to_sym unless letter.nil?
|
14
17
|
@is_terminal = word.empty?
|
15
|
-
@word = get_parent_letter_string if terminal?
|
16
18
|
add_branch_from(word)
|
17
19
|
end
|
18
|
-
|
19
20
|
end
|
20
21
|
|
21
22
|
def terminal=(terminal)
|
@@ -26,22 +27,9 @@ module Rambling
|
|
26
27
|
@is_terminal
|
27
28
|
end
|
28
29
|
|
29
|
-
def [](key)
|
30
|
-
@children[key]
|
31
|
-
end
|
32
|
-
|
33
|
-
def has_key?(key)
|
34
|
-
@children.has_key?(key)
|
35
|
-
end
|
36
|
-
|
37
|
-
def as_word
|
38
|
-
raise InvalidTrieOperation.new() unless @letter.nil? or terminal?
|
39
|
-
@word
|
40
|
-
end
|
41
|
-
|
42
30
|
def add_branch_from(word)
|
43
31
|
unless word.empty?
|
44
|
-
first_letter = word.slice(0)
|
32
|
+
first_letter = word.slice(0).to_sym
|
45
33
|
|
46
34
|
if @children.has_key?(first_letter)
|
47
35
|
word.slice!(0)
|
@@ -54,27 +42,42 @@ module Rambling
|
|
54
42
|
|
55
43
|
def has_branch_for?(word)
|
56
44
|
return true if word.empty?
|
57
|
-
|
45
|
+
branch_exists_and(word) { |node, sliced_word| node.has_branch_for?(sliced_word) }
|
46
|
+
end
|
47
|
+
|
48
|
+
def as_word
|
49
|
+
raise InvalidTrieOperation.new() unless @letter.nil? or terminal?
|
50
|
+
get_letter_string
|
58
51
|
end
|
59
52
|
|
60
53
|
def is_word?(word)
|
61
54
|
return true if word.empty? and terminal?
|
62
|
-
|
55
|
+
branch_exists_and(word) { |node, sliced_word| node.is_word?(sliced_word) }
|
63
56
|
end
|
64
57
|
|
65
58
|
protected
|
66
|
-
def
|
59
|
+
def get_letter_string
|
67
60
|
if @parent.nil?
|
68
|
-
@letter or ''
|
61
|
+
@letter.to_s or ''
|
69
62
|
else
|
70
|
-
@parent.
|
63
|
+
@parent.get_letter_string + @letter.to_s
|
71
64
|
end
|
72
65
|
end
|
73
66
|
|
67
|
+
def parent=(parent)
|
68
|
+
@parent = parent
|
69
|
+
end
|
70
|
+
|
74
71
|
private
|
75
|
-
|
72
|
+
|
73
|
+
def branch_exists_and(word, &block)
|
76
74
|
first_letter = word.slice!(0)
|
77
|
-
|
75
|
+
|
76
|
+
unless first_letter.nil?
|
77
|
+
first_letter = first_letter.to_sym
|
78
|
+
return block.call(@children[first_letter], word) if @children.has_key?(first_letter)
|
79
|
+
end
|
80
|
+
|
78
81
|
false
|
79
82
|
end
|
80
83
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rambling-trie
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -17,9 +17,11 @@ executables: []
|
|
17
17
|
extensions: []
|
18
18
|
extra_rdoc_files: []
|
19
19
|
files:
|
20
|
+
- ./lib/children_hash_deferer.rb
|
20
21
|
- ./lib/invalid_trie_operation.rb
|
21
22
|
- ./lib/rambling-trie.rb
|
22
23
|
- ./lib/trie.rb
|
24
|
+
- ./lib/trie_compressor.rb
|
23
25
|
- ./lib/trie_node.rb
|
24
26
|
homepage: http://rubygems.org/gems/rambling-trie
|
25
27
|
licenses: []
|