Stack Overflow em Português Asked by Elias teixeira on September 27, 2021
Utilizando a linguagem Python, escreva uma função recursiva que determine quantas vezes um número k
de 2 dígitos ocorre em um número natural n
. Por exemplo, o numero 21 ocorre duas vezes em 2135219877.
O problema do meu código é que ele só conta o numero de dois dígitos quando só há dois dígitos no numero a ser avaliado. Como posso arrumar isso?
def verifica(num,c,aux):
if num==0:
return c
else:
if aux==(num//10):
c+=1
num=num//10
return verifica(num,c,aux)
else:
num=num//10
return verifica(num,c,aux)
print('numero',aux,'encontrado',c,'vezes')
c=0
num=int(input('digite um numero: '))
aux=int(input('digite o numero que procura: '))
verifica(num,c,aux)
print('encontrei',aux,c,'vezes.')
Apenas para constar, recursão não é a forma mais eficiente de resolver este problema. Dito isso, vamos à solução.
Um dos problemas da sua função é que eu posso chamá-la assim: verifica(num, -190, aux)
e pronto, já baguncei a contagem, pois o contador começará em -190. Se o contador deve sempre começar em zero, ele não deveria ser um parâmetro.
A ideia básica do algoritmo é:
n
, se forem iguais a k
, incremento o contadorn
por 10 (eliminando assim o último dígito) e continuo a contagemn
chegar a zero, fim do algoritmoAssumindo que o número k
sempre tem 2 dígitos (já que isso não é verificado), ficaria assim:
def verifica(n, k):
if n == 0:
return 0
if n % 100 == k:
c = 1
else:
c = 0
return c + verifica(n // 10, k)
n, k = 2135219877, 21
print(f'O número {k} ocorre {verifica(n, k)} vezes no número {n}')
Como um return
retorna o valor e encerra a execução da função, o bloco else
no primeiro if
é desnecessário. Também tirei o print
de dentro da função, pois ela só deveria retornar o valor, e quem a chama que faça o que quiser com ele (inclusive imprimir, se for o caso). Sem contar que, por ser recursiva, são feitas várias chamadas (uma para cada dígito de n
) e aí seriam impressas várias mensagens, desnecessariamente.
Para obter os 2 últimos dígitos de n
, basta pegar o resto da divisão por 100, usando o operador %
. Depois eu vejo se é igual a k
, e somo 1 se for o caso.
Depois, esse valor é somado com o resultado da contagem no restante do número (o resultado da divisão de n
por 10).
Vale lembrar que verifica(111, 11)
retorna 2
, pois os 2 últimos dígitos de 111 são 11, e depois eu divido 111 por 10, resultando em 11, o que contabiliza outra ocorrência de 11.
Como já dito, o algoritmo funciona apenas se k
tiver exatamente 2 dígitos (ou se for menor que 10, por exemplo, se n
for 10303
e k
for 3
, a contagem contabiliza 2
).
Mas se a ideia é deixar o algoritmo mais "genérico", você pode verificar a quantidade de dígitos de k
e usar esse valor no cálculo - de forma geral, se k
tiver x
dígitos, basta pegar o resto da divisão por 10x.
Outro detalhe é que não precisa ir até n
ser igual a zero. Se n
for menor que k
, já posso parar a verificação, pois a partir daí não terá mais nenhuma ocorrência:
import math
def qtd_digitos(numero):
numero = abs(int(numero))
return (1 if numero == 0 else math.floor(math.log10(numero)) + 1)
def verifica(n, k):
if n < k:
return 0
if n % (10 ** qtd_digitos(k)) == k:
c = 1
else:
c = 0
return c + verifica(n // 10, k)
Lembrando que a solução recursiva não é a ideal para este caso. Isso porque muitas chamadas recursivas podem causar um estouro de pilha se a quantidade de chamadas for suficientemente grande.
Nesse caso, um loop simples já resolve. Além disso, falta verificar alguns corner cases, quando ambos os valores são zero, ou quando somente k
é zero:
import math
def qtd_digitos(numero):
numero = abs(int(numero))
return (1 if numero == 0 else math.floor(math.log10(numero)) + 1)
def verifica(n, k):
if n == 0 and k == 0:
return 1
c = 0
qtd = qtd_digitos(k)
while (k == 0 and n > k) or (k != 0 and n >= k):
if n % (10 ** qtd) == k:
c += 1
n //=10
return c
print(verifica(0, 0)) # 1
print(verifica(100, 0)) # 2
Correct answer by hkotsubo on September 27, 2021
Get help from others!
Recent Questions
Recent Answers
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP