Qui ci sono un paio di modi per contare il numero di volte una data sottostringa appare in una stringa (il primo è la mia preferenza). Nota (come confermato dalla OP) sottostringa 'aa'
appare due volte nella stringa 'aaa'
, e quindi cinque volte a:
string="aaabbccaaaaddbb"
# 1
Utilizzare String#scan con una regex che contiene un lookahead positivo cerca la stringa:
def count_em(string, substring)
string.scan(/(?=#{substring})/).count
end
count_em(string,"aa")
#=> 5
Nota:
"aaabbccaaaaddbb".scan(/(?=aa)/)
#=> ["", "", "", "", ""]
Un lookbehind positiva produce lo stesso risultato:
"aaabbccaaaaddbb".scan(/(?<=aa)/)
#=> ["", "", "", "", ""]
# 2
Converti in una matrice, applicare Enumerable#each_cons, quindi unire e contare:
def count_em(string, substring)
string.each_char.each_cons(substring.size).map(&:join).count(substring)
end
count_em(string,"aa")
#=> 5
Abbiamo:
enum0 = "aaabbccaaaaddbb".each_char
#=> #<Enumerator: "aaabbccaaaaddbb":each_char>
Possiamo vedere gli elementi che generati da questo enumeratore convertendolo in un array:
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)>
Convertire enum1
di un array per vedere quali valori l'enumeratore passerà al 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
Si prega di chiarire (con una modifica): '' aa'' appare una o due volte nella stringa ''aaa''. –
Probabilmente dovrebbe essere il doppio in questo caso.Posizioni 0 e 1 && Posizioni 1 e 2 – Johnson
Certo, sei un poster eccellente. Ti ho premiato Cary Swoveland. – Johnson