这里有几种方法可以计算给定子字符串在字符串中出现的次数(第一种是我的偏好)。注意(由 OP 确认)子字符串 'aa' 在字符串 'aaa' 中出现两次,因此在:
string="aaabbccaaaaddbb"
#1
将String#scan 与正则表达式一起使用,该正则表达式包含寻找子字符串的正向前瞻:
def count_em(string, substring)
string.scan(/(?=#{substring})/).count
end
count_em(string,"aa")
#=> 5
注意:
"aaabbccaaaaddbb".scan(/(?=aa)/)
#=> ["", "", "", "", ""]
积极的回溯会产生相同的结果:
"aaabbccaaaaddbb".scan(/(?<=aa)/)
#=> ["", "", "", "", ""]
同样,String#scan 可以替换为 String#gsub。
#2
转换为数组,应用Enumerable#each_cons,然后加入并计数:
def count_em(string, substring)
string.each_char.each_cons(substring.size).map(&:join).count(substring)
end
count_em(string,"aa")
#=> 5
我们有:
enum0 = "aaabbccaaaaddbb".each_char
#=> #<Enumerator: "aaabbccaaaaddbb":each_char>
我们可以通过将枚举器转换为数组来查看将生成的元素:
enum0.to_a
#=> ["a", "a", "a", "b", "b", "c", "c", "a", "a", "a",
# "a", "d", "d", "b", "b"]
enum1 = enum0.each_cons("aa".size)
#=> #<Enumerator: #<Enumerator: "aaabbccaaaaddbb":each_char>:each_cons(2)>
将enum1 转换为数组,看看枚举器将传递给map 的值是什么:
enum1.to_a
#=> [["a", "a"], ["a", "a"], ["a", "b"], ["b", "b"], ["b", "c"],
# ["c", "c"], ["c", "a"], ["a", "a"], ["a", "a"], ["a", "a"],
# ["a", "d"], ["d", "d"], ["d", "b"], ["b", "b"]]
c = enum1.map(&:join)
#=> ["aa", "aa", "ab", "bb", "bc", "cc", "ca",
# "aa", "aa", "aa", "ad", "dd", "db", "bb"]
c.count("aa")
#=> 5