2010-12-20 36 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

相關問題