Nếu bạn đang xử lý một tập dữ liệu lớn, tôi khuyên bạn nên xem xét triển khai điều này như một bộ ba. Tôi đã ném cùng nhau một chút Ruby nhỏ để làm điều này:
require 'rubygems'
require 'redis'
class RedisTrie
TERMINAL = '+'
def initialize(prefix)
@prefix = prefix
@r = Redis.new
end
def add_word(word)
w = word.gsub(/[^a-zA-Z0-9_-]/, '')
key = "#{@prefix}:"
w.each_char do |c|
@r.zset_add key, c.bytes.first, c
key += c
end
@r.zset_add key, 0, TERMINAL
end
def add_words(*words)
words.flatten.compact.each {|word| add_word word}
end
def suggest(text)
@r.zset_range("#{@prefix}:#{text}", 0, -1).map do |c|
(c == TERMINAL) ? text : suggest(text + c)
end.flatten
end
end
rt = RedisTrie.new('trie')
rt.add_words %w( apple automobile carwash oil-change cranky five ruthie axe auto )
p rt.suggest(ARGV.shift.to_s)
Ví dụ:
$ ruby RedisTrie.rb
["apple", "auto", "automobile", "axe", "carwash", "cranky", "five", "oil-change", "ruthie"]
$ ruby RedisTrie.rb a
["apple", "auto", "automobile", "axe"]
$ ruby RedisTrie.rb au
["auto", "automobile"]
$ ruby RedisTrie.rb aux
[]
Đọc thêm về Thử nghiệm tại mục nhập Wikipedia về Thử nghiệm.
Bạn chắc chắn sẽ muốn tối ưu hóa phương pháp đề xuất của mình để không trả về TẤT CẢ các giá trị, thay vào đó chỉ trả về giá trị X đầu tiên mà nó tìm thấy. Nó sẽ đánh bại mục đích lặp lại toàn bộ cấu trúc dữ liệu.