Eu preciso de uma função que leva n e retorna 2 n - 1 . Parece bastante simples, mas a função precisa ser recursiva. Até agora eu tenho apenas 2 n :
def required_steps(n):
if n == 0:
return 1
return 2 * req_steps(n-1)
O exercício declara: "Você pode assumir que o parâmetro n é sempre um número inteiro positivo e maior que 0"
1 << n
não podem exceder. Este parece ser um exercício de inventar uma maneira de decompor-se(1<<n) - 1
em várias etapas, talvez definindo cada bit um de cada vez, como mostram algumas respostas.def fn(n): if n == 0: return 1; return (2 << n) - fn(0); # technically recursive
C:\MyFolder
Respostas:
2**n -1
é também 1 + 2 + 4 + ... + 2 n-1 que pode ser transformado em uma única função recursiva (sem a segunda para subtrair 1 da potência de 2).Dica : 1 + 2 * (1 + 2 * (...))
Solução abaixo, não procure se você quiser tentar a dica primeiro.
Isso funciona se
n
é garantido que seja maior que zero (como foi realmente prometido na declaração do problema):Uma versão mais robusta também lidaria com valores zero e negativos:
(Adicionar uma verificação para números não inteiros é deixado como um exercício.)
fonte
required_steps(0)
agora causa recursão infinita2^0 - 1
== 0. Adicione outroif
para esse caso.int
, não sabemos o que fazer quando n <0. Calcular? Lançar um erro? Retornar 0? Nesse caso, só podemos fazer uma função parcial (defina-a para coisas que sabemos qual é o resultado).0
e é usadon - 1
para o subproblema. Um domínio de números naturais parece ser um bom ajuste.Para resolver um problema com uma abordagem recursiva, você teria que descobrir como definir a função com uma entrada especificada em termos da mesma função com uma entrada diferente. Nesse caso, desde
f(n) = 2 * f(n - 1) + 1
, você pode fazer:de modo a:
saídas:
fonte
Você pode extrair a parte realmente recursiva para outra função
Ou você pode definir um sinalizador e definir exatamente quando subtrair
fonte
Usando um parâmetro adicional para o resultado,
r
-Você também pode escrevê-lo usando o deslocamento à esquerda bit a bit,
<<
-A saída é a mesma
fonte
else
cláusula em qualquer funçãor * 2
parar << 1
e "isso não é legível"? 😂n
vezes e, em seguida, subtrai 1. Parece ainda menos elegante, então, necessário, embora a coisa toda é um exercício de ineficiência vs.(1<<n) - 1
.Tenha um espaço reservado para lembrar o valor original de n e, em seguida, para o primeiro passo
n == N
, ou seja , retornar2^n-1
fonte
Uma maneira de obter o deslocamento de "-1" é aplicá-lo no retorno da primeira chamada de função usando um argumento com um valor padrão e defina explicitamente o argumento de deslocamento como zero durante as chamadas recursivas.
fonte
Além de todas as respostas impressionantes fornecidas anteriormente, a seguir mostramos sua implementação com funções internas.
Basicamente, está atribuindo um valor global de n a ke recorrendo a ele com comparações apropriadas.
fonte