在Ruby中生成抽象键的算法

时间:2017-02-15 21:26:59

标签: ruby algorithm

我有一个每个字母的数组

    alphabet = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"]

    input ="cg?" 

然后我创建子键

    sub_keys = (2..letters.length).flat_map do |n|
      letters.combination(n).map(&:join).map{|n| n = n.length.to_s + n.chars.sort.join } 
    end.uniq

哪个给了我

    sub_keys = ["2?c, 2?g, 2cg, 3cg?"]

现在我想转换我的sub_keys以获得预期的输出

    keys = [2ac, 2bc, 2cc, 2c, 2ag, 2bg, 2cg, 2dg, 2eg, 2fg, 2gg, 2g, 3acg, 3bcg, 3ccg, 3cdg, 3ceg, 3cfg, 3cgg, 3cg]

正如你所看到的那样,一些键如:2c,2g,3cg从其他键中脱颖而出。在我的代码2c充当2cd,2ce,2cf等..这是我想要的输出,我的代码在这里:

    keys_with_blanks = sub_keys.select{ |k| k.include? "?" }.map{ |k| k.gsub("?","") }
    keys = keys_with_blanks.map do |k| 
      current_letters = choose_letters(all_letters, k)
      k = current_letters.map{ |l| l.gsub(l,l+k) } 
    end.flatten.map{ |k| k.chars.sort.join }.uniq
    keys += keys_with_blanks 

为了在输入增长时减少密钥,我决定在每次迭代中仅选择字母表中我需要的字母而不是所有字母,因此行current_letters = choose_letters(all_letters, k) choose_letters:

    def choose_letters(letters, key)
      letters = letters.select{ |l| l <= key.chars.last }
    end

如果我有一个密钥key = "2c",那么choose_letters将返回["a","b","c"]

这样我只能制作我需要的钥匙。最多约13个字符输入它非常快。输入长度为14或15个字符时,问题就开始了。然后制作所有按键需要3到4秒。

这是缓慢的部分

     keys = keys_with_blanks.map do |k| 
       current_letters = choose_letters(all_letters, k)
       k = current_letters.map{ |l| l.gsub(l,l+k) } 
     end.flatten.map{ |k| k.chars.sort.join }.uniq

input = "abcdefghijklmn?"

大约需要3-4秒

问题

如何重构代码以更快地生成密钥?我的最新升级是实施choose_letters方法,所以像&#34; 2cd&#34;,&#34; 2ce&#34;,&#34; 2cf&#34;不会产生,因为它们的工作方式与&#34; 2c&#34;完全相同。现在它只生成我需要的键,所以它的速度要快一点,但仍然可以更快?

0 个答案:

没有答案