Reputation: 77
I want to make a word unscarambler in ruby. say if I have a words in array
words = ["foo","ofo"]
how can I compare this to another string like "oof" and returning true value
Upvotes: 1
Views: 3352
Reputation: 110755
This can be done as follows.
words = ["foo", "ofo", "goo"]
target = "foo"
target_size = target.size
#=> 3
target_sorted = target.each_char.sort
#=> ["f", "o", "o"]
words.select { |w| anagram?(target_size, target_sorted, w) }
#=> ["foo", "ofo"]
The typical way anagram?
is written is:
def anagram?(target_size, target_sorted, w)
return false unless w.size == target_size
w.each_char.sort == target_sorted
end
However, I've wondered it might be faster to:
target
i
of a matching character in w
w[i]
i #=> nil
), return false
true
if false
is not returned earlierThis can be implemented thus:
def anagram?(target_size, target, w)
return false unless target.size == w.size
wcpy = w.dup
target.each_char do |c|
i = wcpy.index(c)
return false unless i
wcpy[i] = ''
end
true
end
words.select { |w| anagram?(target_size, target, w) }
#=> ["foo", "ofo"]
I'll have to benchmark the two one day.
We could also write:
def anagram?(w1, w2)
return false unless w1.size == w2.size
w1.chars.difference(w2.chars).empty?
end
The helper Array#difference
is defined here.
Upvotes: 2
Reputation:
If all the strings in the array are permutations of each other then:
words = ["foo", "ofo"]
str = "foo"
words[0].split("").sort == str.split("").sort
Upvotes: 1