2010-12-20 107 views
2

我已经得到了一些字: hello, poison, world, search, echo ... 我已经得到了一些信件e, h, o 现在我需要找到一个包括该字母的所有单词。像search, echoe, h, o正则表达式:如果三个字母都包含

我可以搜索这种方式:

words = %w[hello poison world search echo] 
matched = words.select do |w| 
    %w[e,h,o].all?{ |l| w =~ /#{l}/ } 
end 

的问题是,如果字母是o, o, o,或l, b, l这个搜索将像openboil话返回true,但我需要搜索词包括的o三个或两个的l和一个b

UPD:

leters = "abc" 
words.select{ |w| w.count(letters) >= 3 } 

UPD 2

坏的解决方案,例如:

"lllllll".count("lua") #=> 5 
+0

多少个字如果要在一个良好的性能?整个字典,该解决方案将是不同的。 – 2010-12-20 14:06:55

+0

多大的文字吗?而且你会需要对其运行几个3个字母集? – 2010-12-20 14:07:03

+0

约500-1000字(它是数组,acctually),而我也跑几设置(每次20-30) – fl00r 2010-12-20 14:20:12

回答

1

您确定要检查正则表达式吗?字符串支持计数值,您可以使用该功能。事情是这样的:

words = ["pool", "tool", "troll", "lot"] 
letters = "olo" 

#find how many of each letter we need 
counts = {} 
letters.each { |v| counts[v] = letters.count(v) } 

#See if a given work matches all the counts 
# accumulated above 
res = words.select do |w| 
    counts.keys.inject(true) do |match, letter| 
     match && (w.count(letter) == counts[letter]) 
    end 
end 
+0

为什么我们不能只用'words.select {| w | w.count(字母)}' – fl00r 2010-12-20 14:47:11

+0

明白了。我喜欢这种方式。谢谢! – fl00r 2010-12-20 15:13:54

1

这也可能是最好不要使用正则表达式这一点,但它可以做到:

所有三个字母不同:

/^(?=.*a)(?=.*b).*c/ 

两个相同和不同的一个:

/^(?=.*a.*a).*b/ 

所有这三个相同:

/^.*a.*a.*a/ 
+0

如何在没有正则表达式的情况下解决此问题? – fl00r 2010-12-20 13:54:08

+0

@floor:计算目标三个字母中每个字母的频率,然后对每个字母检查它是否至少出现在您正在测试的单词中的次数。 – 2010-12-20 13:55:15

1

考虑修改字(使之成为与每个检查更小)。

words = %w(fooo for find o ooo) 
matched = words.select do |orig| 
    # note: str.gsub! returns nil if nothing was replaced 
    w = orig.clone 
    %w(o o o).all?{ |l| w.gsub!(/^(.*)(#{l})(.*)$/, '\1\3') } 
end 
0

看起来很疯狂,但它的工作原理:

leters = "abc" 
words.select{ |w| w.count(letters) >= 3 } 

但它不是用西里尔字母:(工作

+0

广义化:'words.select {| w | w.count(letters)> = letters.size}' – 2010-12-20 14:57:12

+1

一个严重的问题:''lllll“。count(alo)#=> 5' :( – fl00r 2010-12-20 15:04:34

+0

用'jcount'固定的西里尔字母 – fl00r 2010-12-20 15:09:16

相关问题