6
respostas

Dados dois strings (um contendo uma frase e outro contendo uma palavra), determine o número de vezes que a palavra ocorre na frase.

Dados dois strings (um contendo uma frase e outro contendo uma palavra), determine o número de vezes que a palavra ocorre na frase.

Exemplo: Para a palavra ANA e a frase : ANA E MARIANA GOSTAM DE BANANA

Temos que a palavra ocorre 4 vezes na frase.

A minha tentativa:

def n_vezes(frase, palavra):
    cont = 0
    for p in frase.split():
        if palavra in p:
            cont += 1
    return cont


frase = "ANA E MARIANA GOSTAM DE BANANA"
palavra = "ANA"

print(n_vezes(frase, palavra))

O problema é que meu programa retornar 3 e não 4... Alguma ideia?

6 respostas

Utilize o built-in find(), ele tem parâmetros adicionais onde você pode dizer para ele "de qual posição até qual posição" ele deve pesquisar.

sentence = "ANA E MARIANA GOSTAM DE BANANA DANABANA"
word = "ANA"

def searchWord(word, sentence): #procurar a palavra na frase
    count = 0 #Contador
    position = 0 #Posição inicial para pesquisa

    while position < len(sentence): #Enquanto a posição de pesquisa não chegar no final da palavra
        index = sentence.find(word, position, len(sentence)) #procura a palavra da Posição atual até o final da frase
        if(index != -1): #se encontrar, retornará a posição inicial da palavra, senão retornará -1
            count += 1 #se retornar a posição, então incrementamos o contador em 1
        else:
            break #se retornou -1 então não encontrou mais nenhuma palavra chave dentro da frase, saímos do loop
        position = index + 1 #nova posição de pesquisa = próxima letra após a posição inicial da palavra encontrada

    return count #retorna quantas palavrás há na frase


print(f'{searchWord(word, sentence)}')

Função crua sem comentários:

def search_word(word_, sentence_):
    count = 0
    position = 0

    while position < len(sentence_):
        index = sentence_.find(word_, position, len(sentence_))
        if index != -1:
            count += 1
        else:
            break
        position = index + 1

    return count

Olá,

O retorno não é o que você estava esperando pois ao fazer "ANA" in "BANANA" há o resultado True ao encontrar a primeira ocorrência de "ANA", não buscando outras ocorrências de "ANA" na palavra. A solução para isso é percorrer letra a letra a sua frase buscando pela palavra.

Vou fazer de duas formas:

# Usando conhecimento básico porém de maneira trabalhosa e mais complexa do que o necessário
def n_vezes(frase, palavra):
    # Definindo contador de ocorrências
    cont = 0
    # Percorrendo a frase letra a letra
    for i in range(len(frase)):
        # Definindo contador auxiliar para comparar letra a letra a similaridade
        cont2 = 1
        if frase[i] == palavra[0] and len(palavra) != 1:
            for j in range(1, len(palavra)):
                if i+j < len(frase):
                    if frase[i+j] == palavra[j]:
                        cont2 += 1
                    if cont2 == len(palavra):
                        cont += 1
        # Condição para o caso da palavra possuir apenas um caractere
        elif frase[i] == palavra[0] and len(palavra) == 1:
            cont += 1
    return cont


frase = "ANA E MARIANA GOSTAM DE BANANA"
palavra = "ANA"

print(n_vezes(frase, palavra))

Usando Regular Expression:

from re import compile

frase = "ANA E MARIANA GOSTAM DE BANANA"
palavra = "ANA"
pattern = compile(palavra)
start = 0
count = 0
while start < len(frase):
    if pattern.search(frase[start:]):
        count += 1
        start += pattern.search(frase[start:]).start()
    start += 1
print(count)

Espero ter ajudado.

Abraços

Obrigado, Thiago Matos e Jefferson Peralva Machiqueira. vou estudar o código!

Jefferson Peralva Machiqueira, poderia por favor comentar a solução com regex? nao entendi muito bem.

Olá Edson,

A primeira coisa a observar é que o algoritmo que está buscando precisa considerar a sobreposição das letras. Se não precisasse considerar, sua solução iria causar a sensação de resposta correta, pois "BANANA" só tem duas "ANA" sobrepondo a letra "A" que está em negrito. Se não fosse isso a solução seria muito mais simples como segue abaixo:

frase = "ANA E MARIANA GOSTAM DE BANANA"
palavra = "ANA"
print(frase.count((palavra)))

# Imprime 3, como no seu algoritmo

Ainda assim seu algoritmo retornaria o valor errado sem sobreposição conforme o exemplo abaixo:

frase = "ANA E MARIANA GOSTAM DE BANANAANA"
palavra = "ANA"
print(frase.count((palavra)))

# Este novo algoritmo simples iria imprimir 4 quando neste caso você estaria esperando 5
# Seu algoritmo original iria continuar imprimindo 3 pois além de não considerar as sobreposições, conta apenas a primeira ocorrência na palavra em cada palavra

Posta esta introdução, podemos dizer que temos a compreensão do problema:

  • Contar as ocorrências de determinado padrão em uma frase
  • Considerar os overlaping (todos os métodos disponíveis no patote "re" do python são non-overlaping, se não quisesse contar os overlaping a solução seria ainda mais simples)

Desta forma, segue o código comentado:

# Importando compile de re
from re import compile


frase = "ANA E MARIANA GOSTAM DE BANANA"
palavra = "ANA"

pattern = compile(palavra)    # "Compilando" o padrão /ANA/
start = 0                     # Marcador de posição de início na frase
count = 0                     # Contador de ocorrências
while start < len(frase):     # posição na frase tem que ser menor que o tamanho da frase, caso contrarío haverá um IndexError
    if pattern.search(frase[start:]):                   # Entra no bloco caso encontre uma ocorrência do padrão usando string slicing 
        count += 1                                      # Incrementa contador
        start += pattern.search(frase[start:]).start()  # O .start() faz com que se retorne o índice da frase onde se inicia o padrão encontrado 
    start += 1                # Incrementa a posição na frase em uma unidade. Sem este incremento o script entra em loop infinito pois o mesmo padrão sempre será encontrado
print(count)

Ajudou a entender?

Abraços

Podemos ainda melhorar o código apresentado de tal forma que caso não encontre o padrão na frase, que quebre o laço. Desta forma não precisamos percorrer a frase inteira:

from re import compile


frase = "ANA E MARIANA GOSTAM DE BANANA"
palavra = "ANA"
pattern = compile(palavra)
start = 0
count = 0
while start < len(frase):
    if pattern.search(frase[start:]):
        count += 1
        start += pattern.search(frase[start:]).start() + 1   # Passamos o incremento de uma unidade para esta linha
    else:                                                    # Interrompe o laço caso não encontre mais padrões
        break
print(count)

Abraços