如何查看字符串中出现短语的次数?
例如,假设短语为donut
str1 = "I love donuts!"
#=> returns 1 because "donuts" is found once.
str2 = "Squirrels do love nuts"
#=> also returns 1 because of 'do' and 'nuts' make up donut
str3 = "donuts do stun me"
#=> returns 2 because 'donuts' and 'do stun' has all elements to make 'donuts'
我检查了this SO建议使用include,但只有在donuts
按顺序拼写时才有效。
我想出了这个,但是在"donuts"
的所有元素拼写完成后它不会停止拼写。即"I love donuts" #=> ["o", "d", "o", "n", "u", "t", "s"]
def word(arr)
acceptable_word = "donuts".chars
arr.chars.select { |name| acceptable_word.include? name.downcase }
end
如何查看给定字符串中出现donuts
的次数?没有边缘情况。输入将始终为String
,不会为零。如果它包含donut
的元素,则不应计为1次;它需要包含donuts
,不必按顺序排列。
答案 0 :(得分:4)
<强>代码强>
def count_em(str, target)
target.chars.uniq.map { |c| str.count(c)/target.count(c) }.min
end
<强>实施例强>
count_em "I love donuts!", "donuts" #=> 1
count_em "Squirrels do love nuts", "donuts" #=> 1
count_em "donuts do stun me", "donuts" #=> 2
count_em "donuts and nuts sound too delicious", "donuts" #=> 3
count_em "cats have nine lives", "donuts" #=> 0
count_em "feeding force scout", "coffee" #=> 1
count_em "feeding or scout", "coffee" #=> 0
str = ("free mocha".chars*4).shuffle.join
# => "hhrefemcfeaheomeccrmcre eef oa ofrmoaha "
count_em str, "free mocha"
#=> 4
<强>解释强>
有关
str = "feeding force scout"
target = "coffee"
a = target.chars
#=> ["c", "o", "f", "f", "e", "e"]
b = a.uniq
#=> ["c", "o", "f", "e"]
c = b.map { |c| str.count(c)/target.count(c) }
#=> [2, 2, 1, 1]
c.min
#=> 1
在计算c
时,请考虑传递给块的b
的第一个元素,并将其分配给块变量c
。
c = "c"
然后块计算
d = str.count(c)
#=> 2
e = target.count(c)
#=> 1
d/e
#=> 2
这表示str
包含足够的"c"
以匹配“咖啡”两次。
获得c
的其余计算是相似的。
<强>附录强>
如果str
匹配字符target
的字符必须与target
的字符顺序相同,则可以使用以下正则表达式。
target = "coffee"
r = /#{ target.chars.join(".*?") }/i
#=> /c.*?o.*?f.*?f.*?e.*?e/i
matches = "xcorr fzefe yecaof tfe erg eeffoc".scan(r)
#=> ["corr fzefe ye", "caof tfe e"]
matches.size
#=> 2
"feeding force scout".scan(r).size
#=> 0
需要正则表达式中的问号才能使搜索变得非贪婪。
答案 1 :(得分:2)
解决方案或多或少简单(map(&:dup)
用于避免输入变异):
pattern = 'donuts'
[str1, str2, str3].map(&:dup).map do |s|
loop.with_index do |_, i|
break i unless pattern.chars.all? { |c| s.sub!(c, '') }
end
end
#⇒ [1, 1, 2]
答案 2 :(得分:1)
这是一种有两种变体的方法,一种是字母必须按顺序出现,另一种是顺序无关紧要。在这两种情况下,每个字母的频率都得到尊重,因此“咖啡”必须匹配两个“f”和两个“e”字母,“免费摩卡”不足以匹配,缺少第二个“f”。
def sorted_string(string)
string.split('').sort.join
end
def phrase_regexp_sequence(phrase)
Regexp.new(
phrase.downcase.split('').join('.*')
)
end
def phrase_regexp_unordered(phrase)
Regexp.new(
phrase.downcase.gsub(/\W/, '').split('').sort.chunk_while(&:==).map do |bit|
"#{bit[0]}{#{bit.length}}"
end.join('.*')
)
end
def contains_unordered(phrase, string)
!!phrase_regexp_unordered(phrase).match(sorted_string(string.downcase))
end
def contains_sequence(phrase, string)
!!phrase_regexp_sequence(phrase).match(string.downcase)
end
strings = [
"I love donuts!",
"Squirrels do love nuts",
"donuts do stun me",
"no stunned matches",
]
phrase = 'donut'
strings.each do |string|
puts '%-30s %s %s' % [
string,
contains_unordered(phrase, string),
contains_sequence(phrase, string)
]
end
# => I love donuts! true true
# => Squirrels do love nuts true true
# => donuts do stun me true true
# => no stunned matches true false
答案 3 :(得分:0)
简单的解决方案:
criteria = "donuts"
str1 = "I love donuts!"
str2 = "Squirrels do love nuts"
str3 = "donuts do stun me"
def strings_construction(criteria, string)
unique_criteria_array = criteria.split("").uniq
my_hash = {}
# Let's count how many times each character of the string matches a character in the string
unique_criteria_array.each do |char|
my_hash[char] ? my_hash[char] = my_hash[char] + 1 : my_hash[char] = string.count(char)
end
my_hash.values.min
end
puts strings_construction(criteria, str1) #=> 1
puts strings_construction(criteria, str2) #=> 1
puts strings_construction(criteria, str3) #=> 2