Necesito contar el número de veces que la subcadena 'bob'
ocurre en una cadena.
Problema de ejemplo: encuentre el número de veces que ‘bob’ ocurre en la cadena s tal que
"s = xyzbobxyzbobxyzbob" #(here there are three occurrences)
Aquí está mi código:
s = "xyzbobxyzbobxyzbob" numBobs = 0 while(s.find('bob') >= 0) numBobs = numBobs + 1 print numBobs
Dado que se supone que la función de búsqueda en Python devuelve -1 si una subcadena no está fundada, el bucle while debería finalizar después de imprimir el número incrementado de bobs cada vez que encuentra la subcadena.
Sin embargo, el progtwig resulta ser un bucle infinito cuando lo ejecuto.
Cuando haces una s.find('bob')
que buscas desde el principio, por lo que terminas encontrando la misma bob una y otra vez, necesitas cambiar tu posición de búsqueda para terminar la bobina que encontraste.
string.find
toma un argumento de inicio que puede pasar para decirle desde dónde comenzar la búsqueda, string.find
también devuelve la posición en la que encontró bob, así que puede usar eso, agregarle una longitud de bob y pasarlo a la siguiente s.find
.
Por lo tanto, al inicio del ciclo, establezca start=0
cuando desee buscar desde el inicio, dentro del ciclo si find
devuelve un número no negativo, debe agregarle la longitud de la cadena de búsqueda para obtener un nuevo inicio:
srch = 'bob' start = numBobs = 0 while start >= 0: pos = s.find(srch, start) if pos < 0: break numBobs += 1 start = pos + len(srch)
Aquí estoy asumiendo que la cadena de búsqueda superpuesta no se considera
Para este trabajo, str.find
no es muy eficiente. En su lugar, str.count
debería ser lo que usas:
>>> s = 'xyzbobxyzbobxyzbob' >>> s.count('bob') 3 >>> s.count('xy') 3 >>> s.count('bobxyz') 2 >>>
O bien, si desea que se produzcan superposiciones, puede usar Regex:
>>> from re import findall >>> s = 'bobobob' >>> len(findall('(?=bob)', s)) 3 >>> s = "bobob" >>> len(findall('(?=bob)', s)) 2 >>>
find
no recuerda dónde estaba el partido anterior y comienza desde allí, no a menos que se lo digas. Debe realizar un seguimiento de la ubicación del partido y pasar el parámetro de start
opcional. Si no lo find
solo encontrarás el primer bob
una y otra vez.
find(...) S.find(sub [,start [,end]]) -> int Return the lowest index in S where substring sub is found, such that sub is contained within s[start:end]. Optional arguments start and end are interpreted as in slice notation. Return -1 on failure.
Aquí hay una solución que devuelve el número de sub-cadenas superpuestas sin usar Regex: (Nota: el ‘while’ loop se escribe aquí suponiendo que está buscando una subcadena de 3 caracteres, es decir, ‘bob’)
bobs = 0 start = 0 end = 3 while end <= len(s) + 1 and start < len(s)-2 : if s.count('bob', start,end) == 1: bobs += 1 start += 1 end += 1 print(bobs)
Aquí tienes una función fácil para la tarea:
def countBob(s): number=0 while s.find('Bob')>0: s=s.replace('Bob','',1) number=number+1 return number
Luego, le preguntas a countBob cuando lo necesites:
countBob('This Bob runs faster than the other Bob dude!')
def count_substring(string, sub_string): count=a=0 while True: a=string.find(sub_string) string=string[a+1:] if a>=0: count=count+1; else: break return count