ruby_trie 0.1.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/ruby_trie.rb +178 -0
- metadata +44 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 7b99b117ecaf12bcdde89702426168365cb64e6b
|
4
|
+
data.tar.gz: 7eafccb776fda1922070eb15535ee320219973d3
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 77c32f34f931a65daa2f8c250d66ac4df34944bf97e983e264ffcffd91ce56a217bbbf1551d4faaae042b271aebb4a0961401ebae93c6b0a9c8839d8270c7b18
|
7
|
+
data.tar.gz: 09a2c2c20396b48df18fe6f2ae21719793448db8043ce116ce1b13fb371a25df45f415476723e0cab843141f0fd42a4332249712f8912457949b7de36dc74dc2
|
data/lib/ruby_trie.rb
ADDED
@@ -0,0 +1,178 @@
|
|
1
|
+
# ruby_trie
|
2
|
+
# a pure Ruby trie implementation
|
3
|
+
# because fast-trie is broken and segfaults
|
4
|
+
|
5
|
+
# Stephen Gooberman-Hill@amey.co.uk
|
6
|
+
# (c) Amey Nov 2016
|
7
|
+
# licenced uner the MIT licence
|
8
|
+
|
9
|
+
|
10
|
+
gem 'tree'
|
11
|
+
require 'tree'
|
12
|
+
|
13
|
+
# RubyTrie is a pure Ruby implentation of a Trie based on the
|
14
|
+
# Tree module
|
15
|
+
module RubyTrie
|
16
|
+
# the content of a TrieNode
|
17
|
+
class TrieContent
|
18
|
+
# symbol at the node, and the entire string to this node are held
|
19
|
+
attr_reader :symbol, :string
|
20
|
+
|
21
|
+
# value can be overwritten
|
22
|
+
attr_accessor :value
|
23
|
+
|
24
|
+
# Initialize with the full string (not just the symbol)
|
25
|
+
# and an optional value
|
26
|
+
# You should not need to use this class unless you start
|
27
|
+
# walking the Trie
|
28
|
+
def initialize(str, value=nil)
|
29
|
+
@string = str
|
30
|
+
@symbol = str[-1]
|
31
|
+
@value = value
|
32
|
+
end
|
33
|
+
|
34
|
+
# turn the content into a [symbol, string, value] array
|
35
|
+
def to_a
|
36
|
+
[@symbol, @string, @value]
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
# A TrieNode is a node in the Trie
|
41
|
+
# derives from the TreeNode class
|
42
|
+
# You should only need this class if you use Tree methods
|
43
|
+
# to walk the tree and such-like
|
44
|
+
class TrieNode < Tree::TreeNode
|
45
|
+
# Specialized version of TreeNode
|
46
|
+
|
47
|
+
# adds adds a node at a particular point
|
48
|
+
# if the node already exists, then it will
|
49
|
+
# overwrite the value
|
50
|
+
# :call-seq:
|
51
|
+
# add_node(string, value) -> TrieContent
|
52
|
+
def add_node(string, value)
|
53
|
+
current_node = self.root
|
54
|
+
current_string = ''
|
55
|
+
chars = string.split('')
|
56
|
+
|
57
|
+
chars.each do |c|
|
58
|
+
current_string << c
|
59
|
+
child = current_node[c]
|
60
|
+
unless child
|
61
|
+
child = TrieNode.new(c)
|
62
|
+
current_node.add(child)
|
63
|
+
end
|
64
|
+
current_node = child
|
65
|
+
end
|
66
|
+
|
67
|
+
current_node.content = TrieContent.new(string, value)
|
68
|
+
end
|
69
|
+
|
70
|
+
# return the TreeNode corresponding to a given string
|
71
|
+
# :call-seq:
|
72
|
+
# get_node(string) -> TrieNode
|
73
|
+
|
74
|
+
def get_node(string)
|
75
|
+
current_node = self.root
|
76
|
+
current_string = ''
|
77
|
+
chars = string.split('')
|
78
|
+
|
79
|
+
chars.each do |c|
|
80
|
+
current_string << c
|
81
|
+
current_node = current_node[c]
|
82
|
+
break unless current_node
|
83
|
+
end
|
84
|
+
|
85
|
+
current_node
|
86
|
+
end
|
87
|
+
|
88
|
+
# gets the value at a node
|
89
|
+
# returns nil if the node does not exist
|
90
|
+
# :call-seq:
|
91
|
+
# get_node_value(string) -> Object
|
92
|
+
def get_node_value(string)
|
93
|
+
node = get_node(string)
|
94
|
+
node&.content&.value
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
# Trie implements a Trie structure via an
|
99
|
+
# underlying implementation using Tree
|
100
|
+
# Trie has a single attribute (root) which is the root
|
101
|
+
# TrieNode
|
102
|
+
class Trie
|
103
|
+
#The Trie just holds the root node
|
104
|
+
attr_reader :root
|
105
|
+
|
106
|
+
# create an empty Trie
|
107
|
+
def initialize
|
108
|
+
@root = TrieNode.new('')
|
109
|
+
end
|
110
|
+
|
111
|
+
# add a string with optional value to the Trie
|
112
|
+
# Note - will overwrite the value if the node
|
113
|
+
# already exists
|
114
|
+
# :call-seq:
|
115
|
+
# add(string, value) -> TrieContent
|
116
|
+
|
117
|
+
def add(string, value=true)
|
118
|
+
@root.add_node(string, value)
|
119
|
+
end
|
120
|
+
|
121
|
+
# get the value at a node
|
122
|
+
# returns nil if the node does not exist
|
123
|
+
# :call-seq:
|
124
|
+
# get(string) -> Object
|
125
|
+
def get(string)
|
126
|
+
@root.get_node_value(string)
|
127
|
+
end
|
128
|
+
|
129
|
+
# get all the children of a given prefix
|
130
|
+
# including the prefix, if it exists itself
|
131
|
+
# :call-seq:
|
132
|
+
# children(string) -> Array
|
133
|
+
def children(string)
|
134
|
+
parent = @root.get_node(string)
|
135
|
+
return nil unless parent
|
136
|
+
|
137
|
+
parent.inject([]) do |a,n|
|
138
|
+
a << n.content.string if n.content
|
139
|
+
a
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
# get all the children of a given prefix
|
144
|
+
# with thier values (as a [key,value] pair)
|
145
|
+
# including the prefix, if it exists itself
|
146
|
+
# :call-seq:
|
147
|
+
# children_with_values(string) -> Array
|
148
|
+
def children_with_values(string)
|
149
|
+
parent = @root.get_node(string)
|
150
|
+
return nil unless parent
|
151
|
+
|
152
|
+
parent.inject([]) do |a,n|
|
153
|
+
a << [n.content.string, n.content.value] if n.content
|
154
|
+
a
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
# get the content of all children of a given prefix
|
159
|
+
# including the prefix, if it exists itself
|
160
|
+
# :call-seq:
|
161
|
+
# children_content(string) -> Array
|
162
|
+
def children_content(string)
|
163
|
+
parent = @root.get_node(string)
|
164
|
+
return nil unless parent
|
165
|
+
|
166
|
+
parent.inject([]) do |a,n|
|
167
|
+
a << n.content.to_a if n.content
|
168
|
+
a
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
|
173
|
+
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
|
178
|
+
|
metadata
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ruby_trie
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Stephen Gooberman-Hill
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-11-15 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: A trie is an efficient string storage and search structure
|
14
|
+
email: stephen.gooberman-hill@amey.co.uk
|
15
|
+
executables: []
|
16
|
+
extensions: []
|
17
|
+
extra_rdoc_files: []
|
18
|
+
files:
|
19
|
+
- lib/ruby_trie.rb
|
20
|
+
homepage: http://rubygems.org/gems/ruby_trie
|
21
|
+
licenses:
|
22
|
+
- MIT
|
23
|
+
metadata: {}
|
24
|
+
post_install_message:
|
25
|
+
rdoc_options: []
|
26
|
+
require_paths:
|
27
|
+
- lib
|
28
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
29
|
+
requirements:
|
30
|
+
- - ">="
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
33
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
34
|
+
requirements:
|
35
|
+
- - ">="
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
requirements: []
|
39
|
+
rubyforge_project:
|
40
|
+
rubygems_version: 2.5.1
|
41
|
+
signing_key:
|
42
|
+
specification_version: 4
|
43
|
+
summary: Pure Ruby Trie implemnattion
|
44
|
+
test_files: []
|