Ответ 1
Вот несколько способов подсчитать количество раз, когда данная строка отображается в строке (первая из которых является моим предпочтением). Примечание (как подтверждено OP) подстрока 'aa'
появляется дважды в строке 'aaa'
, и поэтому пять раз в:
string="aaabbccaaaaddbb"
# 1
Используйте String # scan с регулярным выражением, которое содержит положительный lookahead, который ищет подстроку:
def count_em(string, substring)
string.scan(/(?=#{substring})/).count
end
count_em(string,"aa")
#=> 5
Примечание:
"aaabbccaaaaddbb".scan(/(?=aa)/)
#=> ["", "", "", "", ""]
Положительный lookbehind дает тот же результат:
"aaabbccaaaaddbb".scan(/(?<=aa)/)
#=> ["", "", "", "", ""]
# 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