【问题标题】:ruby to unjumble words [closed]红宝石使单词变得混乱[关闭]
【发布时间】:2014-07-02 23:39:11
【问题描述】:

我正在尝试编写一个 ruby​​ 脚本来解读排列的单词,生成所有排列,并在 txt 目录中搜索单词。我遇到了问题。

这是我所拥有的简单概述。

print "Enter Permuted Word:"
words = STDIN.gets.chomp


a = to_array(s)
print a, "\n"


perms = a.permutation(3).to_a.collect do |perm|
perm.join
end
print perms, "\n"

file = file.open("words.txt", "r")
file.read.each_line do |line|
fields = line.chomp.split(",")
words_un = fields[1]
end
file.close

txt 文件看起来像这样

words_un
Aarhus
Aaron
Ababa
aback
abaft
abandon
abandoned
abandoning
abandonment
abandons
abase
...
Zulus
Zurich

【问题讨论】:

  • Ruby on Rails 与这个问题有什么关系?看起来这是纯 Ruby。
  • 把它分解一下,不要一次呈现整个脚本,因为当你这样做时,你的问题是什么根本不清楚。脚本在什么时候停止执行您希望它执行的操作?问一个关于这个的问题——你想让那个位做什么,你当前的代码是什么,输入和预期的输出应该是什么。排序完成后,继续编写脚本,如果再次卡住,请提出下一个问题。 . .
  • @Neil,我相信提问者有一个单词字典和一个字符串,并且只是想知道在字典中形成单词的字符串的字符是否存在排列。 user3637905,您可能会考虑进行编辑以添加一些类似的词来澄清。随意借用我的任何一个。我发现这是一个有趣的问题。
  • 现在有三票可以结束您的问题。如果您希望它继续存在,您需要立即进行编辑以澄清。
  • @Neil,是的,我同意。 OP似乎已经消失的事实无济于事。很郁闷……

标签: ruby arrays string permutation


【解决方案1】:

假设dict 是您的字典中的字符串数组,scrambled 是打乱的单词(字符串)。考虑到scrambled 的所有排列或(更糟)dist 的元素将非常低效。例如,假设一个加扰排列的前两个字母是qz。如果dict 中没有以qz 开头的元素(单词),那么考虑以qz 开头的scrambled 的任何排列都是没有意义的。

数据结构

假设这是我们的字典。

dict = ["dog", "cat", "cow", "emu", "cod", "cobra"]

如果我们只想查看字典中是否有几个打乱的单词,我们可以对每个单词都这样做:

   r = 'mue'.split('').permutation(3).find { |w| dict.include?(w.join) }     
     #=> ["e", "m", "u"]
   r.any? ? r.join('') : nil
     #=> "emu"

   r = 'nvwls'.split('').permutation(3).find { |w| dict.include?(w.join) }     
     #=> nil

更有趣的问题是如何以更有效的方式执行此操作,以检查具有许多排列的大量可能较长的单词。

第一步是重新组织字典以提高查找效率。我不是建议如何做到这一点的最佳人选,因为我不熟悉计算机科学的那个(或任何其他)分支。这是一种使用多级哈希的方法:

dh = { "c"=>{ "a"=>{ "t"=>nil },
              "o"=>{ "b"=>{ "r"=>{ "a"=>nil } }, "w"=>nil, "d"=>nil } },
       "d"=>{ "o"=>{ "g"=>nil } },
       "e"=>{ "m"=>{ "u"=>nil } } }  

dh["c"]“包含”所有以“c”开头的单词; dh["c"]["a"] 包含所有以“ca”开头的单词,依此类推。 dh["c"]["a"]["t"] => nil 表示dh["c"]["a"]["t"].join('') => 'cat' 是字典中的单词之一。我假设你有dh。如果您想获得有关如何从 dict 构造 dh 的建议,也许您可​​以将其作为一个单独的问题提出。

代码

这是一种(递归)方法,可用于查看scrambled 的任何解扰是否包含在dict 中。 (修改它以编译在dict 中找到的所有排列的列表并不难,但这不是我解决的问题。)这个方法是用look_up(dh, scrambled) 调用的。

def look_up(dh, left, used = '')
  left.size.times do |i|
    left_copy = left.dup
    e = left_copy[i]
    left_copy[i] = ''
    v = dh[e]
    case v
    when nil
      (return used + e) if left_copy.empty?
    when Hash
      word = look_up(v, left_copy, used + e)
      return word if word
    end
  end
  nil
end

示例

look_up(dh, "owc")         #=> "cow"
look_up(dh, "mue")         #=> "emu"
look_up(dh, "bocar")       #=> "cobra"
look_up(dh, "esuomhcruhc") #=> nil

说明

假设dh 同上,scrambled => "owc"。那么

left = "owc"
used = ''

left.size              #=> 3
enum = left.size.times #=> #<Enumerator: 3:times>

我们可以将enum 转换为一个数组,看看它将传递给它的块:

enum.to_a              #=> [0, 1, 2]

最初,块变量i 设置为0

left_copy = left.dup  #=> "owc"
e = left_copy[i]      #=> left_copy[0] => "o"
left_copy[i] = ''     #left_copy[i] = '' 
left_copy             #=> "wc"
v = dh[e]             #=> v = dh[0] => nil

dh[0] =&gt; nil,结合left_copy.empty? =&gt; false,表示字典中没有以'o'开头的单词,所以我们回到循环顶部并设置i =&gt; 1,并考虑以'o'开头的单词:

left_copy = left.dup  #=> "owc"
e = left_copy[i]      #=> left_copy[1] => "w"
left_copy[i] = ''     #=> left_copy[1] = ''
left_copy             #=> "oc"
v = dh[e]             #=> v = dh[1] => nil

字典中没有以'w'开头的单词,所以我们用i =&gt; 2再次循环,

searching for words in the dictionary beginning with `'c'`:

e = left_copy[2]      #=> "c"
left_copy[2] = ''     #=> left_copy[2] = ''
left_copy             #=> "ow"
v = dh[2]             #=> {"a"=>{"t"=>nil},
                      #    "o"=>{"b"=>{"r"=>{"a"=>nil}}, "w"=>nil, "d"=>nil}}

这表明字典中有以'ca`` and'co'`开头的单词。

由于v是一个哈希,我们递归调用该方法

word = look_up(v, left_copy, used + e)
  #    look_up({"a"=>{"t"=>nil},
  #             "o"=>{"b"=>{"r"=>{"a"=>nil}}, "w"=>nil, "d"=>nil}},
  #             "ow",
  #             "c")

其他字母的计算过程类似。当发现字典中有字符串"co"表示的单词时:

{ "b"=>{ "r"=>{ "a"=>nil } }, "w"=>nil, "d"=>nil }

我们得出结论,因为这个哈希包含"w"=&gt;nil,所以"cow"在字典中,所以我们在递归链上返回'cow'并完成。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-19
    相关资源
    最近更新 更多