-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathprefixTree.rb
More file actions
177 lines (130 loc) · 3.38 KB
/
Copy pathprefixTree.rb
File metadata and controls
177 lines (130 loc) · 3.38 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
#!/usr/bin/ruby
#coding: utf-8
#
# 20140609
#
# hackerproff@gmail.com
# hackerproff@yandex.ru
#
# Prefix Tree
#
#
#
# getbyte(index) → 0 .. 255
# browsers.include?('Konqueror') #=> false
# arr.unshift(0) #=> [0, 1, 2, 3, 4, 5, 6]
# arr.insert(3, 'apple') #=> [0, 1, 2, 'apple', 3, 4, 5, 6]
# "hello".start_with?("hell")
# "hello".each_byte {|c| print c, ' ' }
# "hello".each_char {|c| print c, ' ' }
class Tree
####################################
private
def tail(in_word)
return String.new(in_word[1, (in_word.length-2)])
end
def initialize
@root = Node.new
return self
end
WORDEND = 0
# sign if prefix also is word
# and simple rule; the sign is always in 0 position !
class Record # like a structure
attr_accessor :key
attr_accessor :next_node
def initialize
@key = nil
@next_node = nil
return self
end
end # class Record
class Node
attr_reader :list
def initialize
@list = Array.new(Record)
return self
end
####################################
public
def add_word!(in_word)
# check word end sign
if (in_word.empty?)
if (!(@list.include?(WORDEND)))
@list.unshift(WORDEND)
end
return true
end
len = @list.length - 1
search_index = len
step = search_index / 2
# check available key
while true do
if (step == 0); step = 1; end;
if (in_word.chr == @list[search_index].key)
return @list[search_index].next_node.add_word!(tail(in_word))
end # if char == key
if (in_word.chr > @list[search_index].key)
if (search_index == len) # in the end of array
@list.insert(search_index, Node.new())
@list[search_index].key = in_word.chr
return @list[search_index].next_node.add_word!(tail(in_word))
end
if (in_word.chr < @list.[search_index + 1].key) # if next value is bigger
@list.insert(search_index, Node.new())
@list[search_index+1].key = in_word.chr
return @list[searhc_index+1].next_node.add_word!(tail(in_word))
else
search_index += step
step /= 2
if (search_index > len); search_index = len; end;
next
end
end # if char > key
if (in_word.chr < @list.[search_index].key)
if (search_index == 0)
if (@list[0] == WORDEND)
@list.insert(0, Node.new())
@list[1].key = in_word.chr
return @list[1].next_node.add_word!(tail(in_word))
else
@list.unshift(Node.new())
@list[0].key = in_word.chr
return @list[0].next_node.add_word!(tail(in_word))
end
else
if (in_word.chr > @list.[search_index - 1].key)
@list.insert((search_index - 1), Node.new())
@list[search_index - 1].key = in_word.chr
return @list[search_index - 1].next_node.add_word!(tail(in_word))
else
search_index -= step
step /=2
if (search_index < 0); search_index = 0; end;
next
end
end
end # if char < key
end # while flag do
end # add_word!
end # class Node
####################################
public
def is_word?(in_word)
return ( (in_word.respond_to? String) && (!(in_string.empty?)))
end
def add_word!(in_word)
if (is_word?(in_word))
return @root.add_word!
else
return false
end
end
def get_words(in_prefix)
if (is_word?(in_word))
return @root.
else
return nil
end
end # get_words
end # class Tree