如何计算字符串元素';在ruby中的另一个字符串中出现?
如何检查短语在字符串中出现的次数 例如,假设短语是如何计算字符串元素';在ruby中的另一个字符串中出现?,ruby,string,Ruby,String,如何检查短语在字符串中出现的次数 例如,假设短语是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 becau
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'
我检查了建议使用include的选项,但它只在donuts
按顺序拼写时起作用
我想到了这个,但在“donuts”
的所有元素都拼写好之后,它仍然没有停止拼写。i、 e.“我喜欢甜甜圈”#=>[“o”、“d”、“o”、“n”、“u”、“t”、“s”]
如何检查给定字符串中出现了多少个
甜甜圈
?没有边缘案例。输入将始终为字符串
,不为零。如果仅包含甜甜圈的元素,则不应将其计为1次出现;它需要包含甜甜圈
,不必按顺序排列。解决方案或多或少都很简单(map(&:dup)
用于避免输入突变):
代码
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
解释
为了
计算<代码> c>代码>时,将代码代码>的第一个元素传递给块并分配给块变量<代码> c<代码> >
c = "c"
然后进行区块计算
d = str.count(c)
#=> 2
e = target.count(c)
#=> 1
d/e
#=> 2
这表明str
包含足够的“c”
,可以匹配“coffee”两次
获得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
正则表达式中的问号是使搜索不贪婪的必要条件。这里有两种方法,一种是字母必须按顺序出现,另一种是顺序无关。在这两种情况下,每个字母的频率都受到尊重,因此“咖啡”必须与两个“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
简单解决方案:
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
此问题的可能副本不是上述问题的副本,因为此处的“do stun”
匹配了“donuts”
,例如,未请求子字符串匹配。不重复。虽然不同,但我在我的帖子中指出了另一个原因:字符串的“顺序”并不重要。也许“订单”不是一个好的描述。抱歉搞混了!正如@mudasobwa所说,donuts
和do stun
都应该返回match。您的解决方案总是令人难以置信的。这是一个令人惊讶的简洁方法,适用于像“donuts”这样的短语,每个字母只有一个实例,但会在“coffee”这样的术语中出现双字母。“免费摩卡咖啡”应该与之匹配吗?
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
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
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