2016-07-01 11 views
0

私は現在通り名のオートコンプリートアルゴリズムを開発中です。 私は、このフォーマットでの私の住所があるパラメータとしてファイルを取得:Ruby - オートコンプリートアルゴリズムのアイデア

City,<SPACE>StreetNumber<SPACE>StreetName\n 

市とStreetNameは完全な単語を完了することができます(そのため市は「ラ・ロシェル」であれば、アルゴリズムは「ラ・ロシェルを表示する必要があります"LまたはRを読んでいる場合)

私はその時点でSTDINから1文字のユーザー入力を受け取ります。あなたはまだ理解していなかった場合はここで

は、いくつかのexemplesです:

/B-ADM-442> ./autoCompletion exampleDict 2>\dev\null < test2 
    l 
    i 
    v 
    2 

    /B-ADM-442> ./autoCompletion exampleDict 2>\dev\null < test2 
    {m} {l} {p} {s} {d} 
    {Li} {Ly} 
    {LILLE, d} {LILLE, v} {LILLE, g} {LILLE, h} {LILLE, p} 
    {1 : LILLE, 30 rue VICTOR danel} {2 : LILLE, 120 boulevard VICTOR hugo} 
    => Lille, 120 boulevard Victor Hugo 

は現在、私は唯一の都市ので、「リール」を完了することができるよ今はちょっとこだわっていると私にはわかりませんどのように完了の残りの部分を行う。

ご質問がある場合はお気軽にお問い合わせください。

#!/usr/bin/env ruby 
    #coding: utf-8 

    require 'set' 

    ## ___________ _____ _____ 
    ## |_ _| ___ \_ _| ___| 
    ## | | | |_//| | | |__ 
    ## | | | /| | | __| 
    ## | | | |\ \ _| |_| |___ 
    ## \_/ \_| \_|\___/\____/ 
    ## 

    class Trie 

     attr_accessor :children, :value, :flag 

     def initialize value=nil 
     @children = {} 
     @value = value 
     @flag = false 
     end 

     def add char 
     val = value ? value + char : char 
     children[char] = Trie.new val 
     end 

     def insert word 
     node = self 
     word.each_char do |char| 
      node.add char if not node.children.has_key? char 
      node = node.children[char] 
     end 
     node.flag = true 
     end 

     def find word 
     node = self 
     word.each_char do |char| 
      return nil if not node.children.has_key? char 
      node = node.children[char] 
     end 
     return node.value 
     end 

     def all_prefixes 
     results = Set.new 
     results.add value if flag 
     return results if children.empty? 

     ap = children.values.collect {|node| node.all_prefixes} 

     reduced = ap.reduce {|a,b| a.merge b} 
     reduced or results 
     end 

     def autocomplete prefix 
     node = self 
     prefix.each_char do |char| 
      return Set.new if not node.children.has_key? char 
      node = node.children[char] 
     end 
     return node.all_prefixes 
     end 

    end 

    ## ______ _____ _____ _____ _____ _____ _ _ _ _   ___   ________ __ 
    ## | _ \_ _/ __ \_ _|_ _| _ | \ | || \ | |/_ \ | ___ \   \// 
    ## | | | | | | |/\/ | | | | | | | | \| || \| |/ /_\ \| |_/ /\   V/
    ## | | | | | | | |  | | | | | | | | . ` || . ` || _ || /  \/ 
    ## | |//_| |_| \__/\ | | _| |_\ \_//|\ || |\ || | | || |\ \   | | 
    ## |___/ \___/ \____/ \_/ \___/ \___/\_| \_/\_| \_/\_| |_/\_| \_|   \_/ 
    ## 

    class Dictionnary 

     def initialize file, trieCity, trieStreet 
     @validLine = /[a-zA-ZáàâäãåçéèêëíìîïñóòôöõúùûüýÿæœÁÀÂÄÃÅÇÉÈÊËÍÌÎÏÑÓÒÔÖÕÚÙÛÜÝŸÆŒ' ._-]+, \d+ [a-zA-Z0-9áàâäãåçéèêëíìîïñóòôöõúùûüýÿæœÁÀÂÄÃÅÇÉÈÊËÍÌÎÏÑÓÒÔÖÕÚÙÛÜÝŸÆŒ' ._-]+/ 
     @streetTypes = Array["allée", "avenue", "boulevard", "chemin", "impasse", "place", "quai", "rue", "square"] 
     @regCity = /[a-zA-ZáàâäãåçéèêëíìîïñóòôöõúùûüýÿæœÁÀÂÄÃÅÇÉÈÊËÍÌÎÏÑÓÒÔÖÕÚÙÛÜÝŸÆŒ' ._-]+/ 
     @regStreetName = /[a-zA-ZáàâäãåçéèêëíìîïñóòôöõúùûüýÿæœÁÀÂÄÃÅÇÉÈÊËÍÌÎÏÑÓÒÔÖÕÚÙÛÜÝŸÆŒ' ._-]+, \d+ ([a-zA-Z0-9áàâäãåçéèêëíìîïñóòôöõúùûüýÿæœÁÀÂÄÃÅÇÉÈÊËÍÌÎÏÑÓÒÔÖÕÚÙÛÜÝŸÆŒ' ._-]+)/ 
     @regStreetNumber = /[a-zA-ZáàâäãåçéèêëíìîïñóòôöõúùûüýÿæœÁÀÂÄÃÅÇÉÈÊËÍÌÎÏÑÓÒÔÖÕÚÙÛÜÝŸÆŒ' ._-]+, (\d+) [a-zA-Z0-9áàâäãåçéèêëíìîïñóòôöõúùûüýÿæœÁÀÂÄÃÅÇÉÈÊËÍÌÎÏÑÓÒÔÖÕÚÙÛÜÝŸÆŒ' ._-]+/ 
     @trieCity = trieCity 
     @trieStreet = trieStreet 
     @trieLine = Trie.new 
     @f_letter = Array.new 
     @city = String.new 
     @street = String.new 
     @cityComplete = false 
     begin 
      @file = File.new(file.to_s, "r") 
     rescue => err 
      puts "Invalid argument" 
      exit 84 
     end 
     counter = 0 
     while line = @file.gets 
      if @validLine.match(line) 
      line[@regCity].split.each {|words|       @f_letter.push(words.downcase)} 
      line[@regCity].split.each {|words|   @trieCity.insert(words.downcase)} 
      street = line.scan(@regStreetName).to_s.split[0].match(@regCity) 
      @trieStreet.insert(line.scan(@regStreetName).last.first) 
      end 
      counter += 1 
     end 
     if counter == 0 
      puts "Invalid argument" 
      exit 84 
     end 
     end 

     def prompt 
     hash = @f_letter.each.each_with_object(Hash.new(0)) {|word, hsh|   hsh[word[0].downcase] += 1} 
     hash = Hash[hash.sort_by {|k, v| [-v, k] }] 
     counter = 1 
     hash.each do |k, _| 
      print "{#{k}}" 
      if counter < 5 && counter < hash.size 
      print " " 
      else 
      print "\n" 
      break 
      end 
      counter += 1 
     end 
     end 

     def handle_input char 
     if @cityComplete == false 
      self.complete_city(char) 
     else 
      self.complete_street(char) 
     end 
     end 

     def complete_city char 
     @city.insert(@city.size, char) 
     array = @trieCity.autocomplete(@city) 
     if array.size == 1 
      @city = array.first.dup 
      @cityComplete = true 
      return 
     end 
     counter = 1 
     array.each do |word| 
      print "{#{word.chars.first((@city.size) + 1).join.capitalize}}" 
      if counter < 5 && counter < array.size 
      print " " 
      else 
      print "\n" 
      break 
      end 
      counter += 1 
     end 
     end 

     def complete_street char 
     puts @city 
     puts char 
     @street.insert(@street.size, char) 
     array = @trieStreet.autocomplete(@street) 
     puts array.inspect 
     end 
    end 

    ## ___________ _____ _____ _____ _ _ _____ 
    ## | _ | ___ \_ _|_ _| _ | \ | |/ ___| 
    ## | | | | |_//| | | | | | | | \| |\ `--. 
    ## | | | | __/ | | | | | | | | . ` | `--. \ 
    ## \ \_//|  | | _| |_\ \_//|\ |/\__//
    ## \___/\_|  \_/ \___/ \___/\_| \_/\____/ 

    if !ARGV[0] 
     puts "Invalid argument" 
     exit 84 
    end 

    if ARGV[0] == "-h" 
     puts "USAGE" 
     puts "\t./autocompletion dictionnary\n\n" 
     puts "DESCRIPTION" 
     puts "\tdictionnary\tfile, containing one address per line,   serving as knowledge base" 
     exit 0 
    end 

    ## ___ ___ ___ _____ _ _ 
    ## | \/ |/_ \|_ _| \ | | 
    ## | . . |/ /_\ \ | | | \| | 
    ## | |\/| || _ | | | | . ` | 
    ## | | | || | | |_| |_| |\ | 
    ## \_| |_/\_| |_/\___/\_| \_/ 


    trie1 = Trie.new 
    trie2 = Trie.new 
    dictionnary = Dictionnary.new(ARGV[0], trie1, trie2) 
    dictionnary.prompt 
    while user_input = STDIN.gets 
     user_input ||= '' 
     user_input.chomp! 
     case user_input 
     when "ABORT" 
     exit 0 
     else 
     if user_input.size > 1 
      exit 84 
     end 
     dictionnary.handle_input(user_input[0]) 
     end 
    end 

おかげで、たぶん、この宝石https://github.com/seamusabshere/fuzzy_matchためのコードを読んで トーマス

+0

これまでに書いたコードを投稿するのを忘れました。 –

+0

@Jordanコードを –

答えて

0

あなたが始めてみるために、readlineと略語(両方とも標準のlibから)を見てください。

require "abbrev" 
require "readline" 
arr = ["Marseille", "Marsan", "Martin"] 

Readline.completion_proc = arr.abbrev.to_proc 

while buffer = Readline.readline(">", true) # true means: keep history. 
    exit if buffer.strip == "quit" 
    p buffer 
end 
  • 自動補完マーティン
  • で結果
  • 歴史がアップすることによってアクセス可能で、キー
  • ダウンhash.to_procが利用できない場合があり、比較的新しいタブを押すと、その「マート(タブ)」により、 。
0

はあなたを助けることができる:)

は、ここでそれはちょっと大きいです、これまでの私のコードですが、私はちょっとルビーのnoobです。 (コメントできないので、回答を投稿する必要があります)

+0

共有してくれてありがとう、私は見ている –

関連する問題