J'ai besoin d'une fonction qui prend n et renvoie 2 n - 1 . Cela semble assez simple, mais la fonction doit être récursive. Jusqu'à présent, je n'ai que 2 n :
def required_steps(n):
if n == 0:
return 1
return 2 * req_steps(n-1)
L'exercice indique: "Vous pouvez supposer que le paramètre n est toujours un entier positif et supérieur à 0"
1 << n
ne peuvent donc pas déborder. Cela semble être un exercice pour inventer un moyen de se décomposer(1<<n) - 1
en plusieurs étapes, en réglant peut-être chaque bit un par un comme le montrent certaines réponses.def fn(n): if n == 0: return 1; return (2 << n) - fn(0); # technically recursive
C:\MyFolder
Réponses:
2**n -1
est également 1 + 2 + 4 + ... + 2 n-1 qui peut être transformé en une seule fonction récursive (sans la seconde pour soustraire 1 de la puissance de 2).Indice : 1 + 2 * (1 + 2 * (...))
Solution ci-dessous, ne cherchez pas si vous voulez essayer l'indice en premier.
Cela fonctionne si
n
est garanti supérieur à zéro (comme promis dans l'énoncé du problème):Une version plus robuste gérerait également les valeurs nulles et négatives:
(L'ajout d'une vérification pour les non-entiers est laissé comme exercice.)
la source
required_steps(0)
provoque maintenant une récursion infinie2^0 - 1
== 0. Ajoutez un autreif
pour ce cas.int
, nous ne savons pas quoi faire lorsque n <0. Calculer? Lancer une erreur? Retour 0? Dans ce cas, nous ne pouvons faire qu'une fonction partielle (définissez-la pour les choses dont nous savons quel est le résultat).0
et utilisen - 1
pour le sous-problème. Un domaine de nombres naturels semble être un bon ajustement.Pour résoudre un problème avec une approche récursive, vous devez trouver comment définir la fonction avec une entrée donnée en termes de la même fonction avec une entrée différente. Dans ce cas, depuis
f(n) = 2 * f(n - 1) + 1
, vous pouvez faire:pour que:
les sorties:
la source
Vous pouvez extraire la partie vraiment récursive vers une autre fonction
Ou vous pouvez définir un indicateur et définir à quel moment soustraire
la source
En utilisant un paramètre supplémentaire pour le résultat,
r
-Vous pouvez également l'écrire en utilisant le décalage gauche au niveau du bit,
<<
-La sortie est la même
la source
else
clause dans l'une ou l'autre fonctionr * 2
pourr << 1
et qui est « pas lisible du tout »? 😂n
fois et puis 1. Semble soustraient encore moins élégante alors nécessaire, même si la chose est un exercice de l' inefficacité par rapport(1<<n) - 1
.Avoir un espace réservé pour se souvenir de la valeur d'origine de n, puis pour la toute première étape, c'est
n == N
-à- dire retourner2^n-1
la source
Une façon d'obtenir l'offset de "-1" consiste à l'appliquer dans le retour du premier appel de fonction à l'aide d'un argument avec une valeur par défaut, puis de définir explicitement l'argument offset à zéro lors des appels récursifs.
la source
En plus de toutes les réponses impressionnantes données précédemment, ci-dessous montrera son implémentation avec les fonctions internes.
Fondamentalement, il attribue une valeur globale de n à k et revient à travers elle avec des comparaisons appropriées.
la source