prefix_tree 1.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 4f64aa5bba6e670976b5fbeb9fe4045af84e48be0e3f9f5601d560d6ec4281fe
4
+ data.tar.gz: f87e303415e69c57a7fbe6c5d6ccef6be8eeb552602748f55ecc6c4d09af727d
5
+ SHA512:
6
+ metadata.gz: 0e9daf017cbdc0de5f457ab0d326a42648e1a3f07f25659249f6cb8c7a1d8cc3466dc260d69b4da46b266f16c8affe03da802edc122a6ef6f7250a8bae61b5ad
7
+ data.tar.gz: dcf40a6123e877375fffaf49902a828b175c1bb642bd4ee86157ba33e9ca750d4cd98455d107ce2dc9fe4639b00791ad12715bb4d68a9ad0ce36d6104cf99644
@@ -0,0 +1,44 @@
1
+ # CSV file reader and writer
2
+
3
+ $LOAD_PATH << '../../lib'
4
+
5
+ require'../prefix_tree'
6
+
7
+ class CsvController
8
+ def initialize(tree = PrefixTree.new)
9
+ @tree = tree
10
+ end
11
+
12
+ def fill_csv
13
+ strings = @tree.dictionary.map { |key, value| [key, value] }
14
+
15
+ CSV.open('dictionary.csv', 'w') do |csv|
16
+ csv << %w[id name]
17
+ strings.each { |string| csv << string }
18
+ end
19
+ end
20
+
21
+ def read_csv
22
+ strings = CSV.parse(File.read('strings_for_tree.csv'), headers: true).by_col[1]
23
+ fill_tree(strings)
24
+ end
25
+
26
+ private
27
+
28
+ def fill_tree(strings)
29
+ strings.each { |string| @tree.add(string) }
30
+ end
31
+ end
32
+
33
+ tree = PrefixTree.new
34
+
35
+ tree.add('dsbh')
36
+ tree.add('mmss')
37
+ tree.delete('dsbh')
38
+ tree.add('string')
39
+
40
+ csv_controller = CsvController.new(tree)
41
+
42
+ csv_controller.read_csv
43
+ csv_controller.fill_csv
44
+
@@ -0,0 +1,80 @@
1
+ # create node class
2
+
3
+ $LOAD_PATH << '../../lib'
4
+
5
+ class Node
6
+ attr_reader :value, :number_size, :children, :is_end_point, :strings_indexs
7
+
8
+ @@nodes = []
9
+
10
+ def self.nodes
11
+ @@nodes
12
+ end
13
+
14
+ def initialize(value = 'root')
15
+ @value = value
16
+ @children ||= []
17
+ @strings_indexs = []
18
+ @number_size = 0
19
+ @@nodes << self
20
+ @is_end_point = false
21
+ end
22
+
23
+ def create_child(char)
24
+ @children << child = Node.new(char)
25
+ child
26
+ end
27
+
28
+ def delete_node
29
+ @children.delete_if { |node| node.number_size.zero? }
30
+ end
31
+
32
+ def to_s
33
+ @value
34
+ end
35
+
36
+ def include?(char)
37
+ @children.any? { |node| node.value == char }
38
+ end
39
+
40
+ def find(char)
41
+ @children.each { |node| return node if node.value == char }
42
+ false
43
+ end
44
+
45
+ def become_end_point
46
+ @is_end_point = true
47
+ end
48
+
49
+ def not_end_point
50
+ @is_end_point = false
51
+ end
52
+
53
+ def increment_size
54
+ @number_size += 1
55
+ end
56
+
57
+ def decrement_size
58
+ @number_size -= 1
59
+ end
60
+
61
+ def add_strings_indexs(index)
62
+ @strings_indexs << index
63
+ end
64
+
65
+ def delete_strings_indexs
66
+ @children.each do |node|
67
+ erase_indexs(node)
68
+ end
69
+ end
70
+
71
+ def delete_element(value)
72
+ @strings_indexs.delete_if { |element| element.eql? value }
73
+ end
74
+
75
+ private
76
+
77
+ def erase_indexs(node)
78
+ @strings_indexs -= node.strings_indexs if node.number_size.zero?
79
+ end
80
+ end
@@ -0,0 +1,159 @@
1
+ # create prefix tree
2
+ $LOAD_PATH << '../lib'
3
+ require 'prefix_tree/node'
4
+
5
+
6
+ WORD_EXIST = 'This word is already exist in prefix tree'
7
+ ADD_NEW_WORD = 'Add new word in prefix tree'
8
+ NO_WORD = 'This word is not in tree'
9
+
10
+ class PrefixTree
11
+ attr_reader :dictionary
12
+
13
+ def initialize
14
+ @root = Node.new
15
+ @number_of_input_strings = 0
16
+ @dictionary = {}
17
+ @dictionary_by_strings = {}
18
+ end
19
+
20
+ def add(input_value)
21
+ input_value = convert_to_string(input_value)
22
+ add_word(input_value.downcase)
23
+ end
24
+
25
+ def delete(input_value)
26
+ return NO_WORD unless find(input_value)
27
+
28
+ decrease_size(input_value)
29
+ delete_string_index(input_value)
30
+ delete_nodes(input_value)
31
+ end
32
+
33
+ def include?(input_value)
34
+ find_prefix_node(input_value) ? true : false
35
+ end
36
+
37
+ def find(input_value)
38
+ node = find_prefix_node(input_value)
39
+ return false unless node
40
+
41
+ node.is_end_point
42
+ end
43
+
44
+ def list(input_value)
45
+ node = @root
46
+ input_value.each_char do |char|
47
+ node = find_node(node, char)
48
+ return false unless node
49
+ end
50
+ write_appropriate_strings(node, input_value)
51
+ end
52
+
53
+ private
54
+
55
+ def write_appropriate_strings(node, input_value)
56
+ if input_value == ''
57
+ puts @dictionary.values
58
+ else
59
+ puts_answer(node.strings_indexs)
60
+ end
61
+ end
62
+
63
+ def puts_answer(indexs)
64
+ indexs.each { |index| puts @dictionary[index] }
65
+ end
66
+
67
+ def add_word(input_value)
68
+ return WORD_EXIST if find(input_value)
69
+
70
+ dictionary_filler(input_value)
71
+ fill_tree(input_value)
72
+ ADD_NEW_WORD
73
+ end
74
+
75
+ def dictionary_filler(input_value)
76
+ add_in_dictionary(input_value)
77
+ end
78
+
79
+ def add_in_dictionary(input_value)
80
+ @number_of_input_strings += 1
81
+ @dictionary_by_strings[input_value] = @number_of_input_strings
82
+ @dictionary[@number_of_input_strings] = input_value
83
+ end
84
+
85
+ def fill_tree(input_value)
86
+ node = @root
87
+ input_value.each_char { |char| node = back_new_node(node, char) }
88
+ node.become_end_point
89
+ end
90
+
91
+ def back_new_node(node, char)
92
+ new_node = create_or_find_node(node, char)
93
+ new_node.add_strings_indexs(@number_of_input_strings)
94
+ new_node.increment_size
95
+ new_node
96
+ end
97
+
98
+ def convert_to_string(input_value)
99
+ input_value.to_s
100
+ end
101
+
102
+ def find_prefix_node(input_value)
103
+ node = @root
104
+ input_value.each_char do |char|
105
+ node = find_node(node, char)
106
+ return false unless node
107
+ end
108
+ node
109
+ end
110
+
111
+ def create_or_find_node(node, char)
112
+ if node.include?(char)
113
+ node.find(char)
114
+ else
115
+ node.create_child(char)
116
+ end
117
+ end
118
+
119
+ def find_node(node, char)
120
+ node.include?(char) ? node.find(char) : false
121
+ end
122
+
123
+ def delete_string_index(input_value)
124
+ index = @dictionary_by_strings[input_value]
125
+ @dictionary.delete(index)
126
+ @dictionary_by_strings.delete(input_value)
127
+ end
128
+
129
+ def decrease_size(input_value)
130
+ node = @root
131
+ input_value.each_char do |char|
132
+ node = node.find(char)
133
+ change_size(node, input_value)
134
+ end
135
+ node.not_end_point
136
+ end
137
+
138
+ def change_size(node, input_value)
139
+ node.decrement_size
140
+ node.delete_element(@dictionary_by_strings[input_value])
141
+ end
142
+
143
+ def delete_nodes(input_value)
144
+ node = @root
145
+ input_value.each_char do |char|
146
+ break unless node
147
+
148
+ delete_nodes_in_node_class(node)
149
+ node = node.find(char)
150
+ end
151
+ end
152
+
153
+ def delete_nodes_in_node_class(node)
154
+ node.delete_strings_indexs
155
+ node.delete_node
156
+ end
157
+ end
158
+
159
+
metadata ADDED
@@ -0,0 +1,45 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: prefix_tree
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - tato
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2022-05-06 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: prefix_tree gem
14
+ email: tzpanchulidze@unisens.ge
15
+ executables: []
16
+ extensions: []
17
+ extra_rdoc_files: []
18
+ files:
19
+ - lib/prefix_tree.rb
20
+ - lib/prefix_tree/csv_controller.rb
21
+ - lib/prefix_tree/node.rb
22
+ homepage: ''
23
+ licenses:
24
+ - MIT
25
+ metadata: {}
26
+ post_install_message:
27
+ rdoc_options: []
28
+ require_paths:
29
+ - lib
30
+ required_ruby_version: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: '0'
35
+ required_rubygems_version: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: '0'
40
+ requirements: []
41
+ rubygems_version: 3.2.32
42
+ signing_key:
43
+ specification_version: 4
44
+ summary: prefix_tree
45
+ test_files: []