Ruby检查列表数组中的一个元素与同一数组中的另一个元素

时间:2015-02-07 19:40:54

标签: ruby arrays

我确定这是一个简单的解决方案,但是我仍然坚持迭代一个单词数组并将第一个单词(最终它的长度)与列表中的每个单词进行比较,然后检查第二个单词反对他们所有人和第三人等等。

如果我有两个选择,我可以做这样的事情

word1 = "weird"
word2 = "wired"

if word1.chars.sort.length == word2.chars.sort.length
  true
else
  false
end
我开始很简单。

修改

有了这些话,我会检查它们是否是字谜。

我有一个包含数千个单词的文本文件。所以 输出将类似于此

There were 17346 anagram words found.
Would you like to list them? (Y/n)> Y
...
weird wider wierd wired wried
weirs wires wiser wries

编辑2

我想编写一个程序,可以在单词列表中找到所有字谜http://en.wikipedia.org/wiki/Anagram。例如,单词" silent"和"听"是字谜。

想象一下字典中有许多字谜,但它们不是有序的,或者相关的,它们具有相同的元素但位置不同,程序会满足于从word.txt文件中读取并找到字谜词,我找到了许多字谜,并可以选择显示我的发现。有这样的样本

...
weird wider wierd wired wried
weirs wires wiser wries
welkin winkle
welkins winkles
welting winglet
weltings winglets
wenchers wrenches
wettish whitest
whale wheal
像这样的事情。

单词=%q(用白色丝网擦拭小翼,有明显的宽度......)

迭代将从欢迎到小翼检查他们是否是anagram 如果是这样的话,可能会存储在一个新的数组中。然后去检查它,依此类推。

5 个答案:

答案 0 :(得分:3)

如果你只想要所有的字谜,你可以做......

words.group_by{|w| w.split('').sort}.values

这会给你一个数组数组,每个数组都是列表中所有相互字谜的单词。

答案 1 :(得分:1)

我并不完全清楚你要做什么,但如果你需要查看长度相同的所有单词,那么这可能会有所帮助:

> words = %w[cat dog fish bird red blue green white pink]
=> ["cat", "dog", "fish", "bird", "red", "blue", "green", "white", "pink"]

> words.group_by{|e| e.length}
=> {3=>["cat", "dog", "red"], 
    4=>["fish", "bird", "blue", "pink"], 
    5=>["green", "white"]}

答案 2 :(得分:1)

如果您的数组是:words = ["wierd", "wired", "wierd", "vafasdfasd"]

您可以将第一个单词与每个单词进行比较:

for i in 0...words.length
    if words[0] == words[i]
        puts true
    else
        puts false
    end
end

但要为数组中的每个其他单词重复此操作,您需要使用嵌套循环。这可以工作

for i in 0...words.length
    for j in i...words.length
        if words[i] == words[j]
            puts true
        else
            puts false
        end
    end
end

假设一个单词不是自己的字谜:

for i in 0...words.length
    for j in i...words.length
        if words[i] == words[j]
            puts false
        elsif words[i].chars.sort == words[j].chars.sort
            puts true
        else
            puts false
        end
    end
end

顺便说一下,我会想象上面不会被视为好的代码。如果你比较anagrams很好,但你可能会比较你可能有两倍的东西(但仍然不想与自己比较)。我认为这是一个更好的解决方案:

for i in 0...(words.length-1)
    for j in i...(words.length-1)
        if words[i].chars.sort == words[j+1].chars.sort && words[i] != words[j+1]
            puts true
        else
            puts false
        end
    end
end

答案 3 :(得分:0)

我同意菲利普的观点,目前尚不清楚你在寻找什么,但这是对你想要做的事情的另一种猜测。

reference_word = "12345"

my_array = %w(weird wired not_wierd not_wired)

my_array.select { |item| item.length == reference_word.length }
        .each { |matched_size| puts matched_size }

{ |matched_size| puts matched_size }替换为您想要处理的与参考词大小匹配的项目

答案 4 :(得分:0)

如果你的问题源于预感过滤字长可能会更快,你可以通过修改@ SteveTurczyn的答案来实现:

words = %w{wierd a wired ow dew wierd vafasdfasd wed wo}
  #=> ["wierd", "a", "wired", "ow", "dew", "wierd", "vafasdfasd", "wed", "wo"] 

words.group_by { |w| w.length }.values.flat_map do |a|
  if (a.size > 1)
    a.group_by{|w| w.split('').sort}.values
  else
    [a]
  end
end
  #=> [["wierd", "wired", "wierd"], ["a"], ["ow", "wo"],
  #    ["dew", "wed"], ["vafasdfasd"]]

步骤:

h = words.group_by { |w| w.length }
  #=> {5=>["wierd", "wired", "wierd"], 1=>["a"], 2=>["ow", "wo"],
  #    3=>["dew", "wed"], 10=>["vafasdfasd"]} 
b = h.values
  #=> [["wierd", "wired", "wierd"], ["a"], ["ow", "wo"],
  #    ["dew", "wed"], ["vafasdfasd"]] 
b.flat_map do |a|
  if (a.size > 1)
    a.group_by{|w| w.split('').sort}.values
  else
    [a]
  end
end
  #=> [["wierd", "wired", "wierd"], ["a"], ["ow", "wo"],
  #    ["dew", "wed"], ["vafasdfasd"]]

b传递到上述块的flat_map的第一个元素,并分配给块变量a,是:

a = ["wierd", "wired", "wierd"]

我们因此执行操作:

if (3 > 1)
  ["wierd", "wired", "wierd"].group_by{|w| w.split('').sort}.values
else
  [["wierd", "wired", "wierd"]]
end

由于3 > 1true

c = ["wierd", "wired", "wierd"].group_by { |w| w.split('').sort }
  #=> {["d", "e", "i", "r", "w"]=>["wierd", "wired", "wierd"]}
d = c.values
  #=> [["wierd", "wired", "wierd"]]

由于我们使用的是flat_map,而不是mapa已映射到数组["wierd", "wired", "wierd"]

b的其他元素的处理方式相似。