Compter le nombre d'occurrences de 0 des entiers de 1 à N
Comment saurez-vous efficacement compter le nombre d'occurrences de 0 dans la représentation décimale des entiers de 1 à N?
e.g. The number of 0's from 1 to 105 is 16. How?
10,20,30,40,50,60,70,80,90,100,101,102,103,104,105
Compter le nombre de ' 0 ' & vous le trouverez à 16.
Évidemment, une approche par force brute ne sera pas apprécié. Vous devez venir avec une approche qui ne dépend pas de "Combien de nombres sont comprises entre 1 à N".
Peut-on juste faire en voyant une sorte de modèle?
Ne peut-on étendre le la logique compilés ici de travailler pour ce problème?
Je pensais que vous n'étiez pas censés fuite de ces questions après une interview 😉
C'est clairement proportionnelle à
il est plus probable dans l'ordre de
J'aime ces sortes de questions. Chance d'une application pratique de l'algorithme à l'extérieur de la salle de classe 0.00000000000000000000000000001%.
Pour faire une distribution de chiffres dans une série, il aide à les compter. en.wikipedia.org/wiki/Benford's_law
C'est clairement proportionnelle à
n^2
, si juste qu'il ne la force brute jusqu'à 10k 100k pour en déduire une constante et vous avez terminé.il est plus probable dans l'ordre de
N log N
je dirais.J'aime ces sortes de questions. Chance d'une application pratique de l'algorithme à l'extérieur de la salle de classe 0.00000000000000000000000000001%.
Pour faire une distribution de chiffres dans une série, il aide à les compter. en.wikipedia.org/wiki/Benford's_law
OriginalL'auteur Green goblin | 2012-08-09
Vous devez vous connecter pour publier un commentaire.
Mise À Jour De Réponse
Ma réponse a été simple à comprendre mais difficile à code. Voici quelque chose qui est plus simple à code. C'est un straight-forward non-récursive solution qui fonctionne en comptant le nombre de façons de zéros peuvent apparaître dans chaque position.
Par exemple:
Il y a 12 possibilités pour l' "des centaines ou plus" (1,2, ..., 12). Il doit y avoir un zéro. Ensuite, il y a 10 possibilités pour le dernier chiffre. Cela donne
12 * 10 = 120
numéros contenant un 0 à la troisième chiffre.La solution pour la plage (1 à 1234) est donc:
Mais une exception est si
n
contient un chiffre zéro. Considérons le cas suivant:Nous avons 12 façons de choisir les "milliers ou plus". Pour 1, 2, ... 11 nous pouvons choisir deux derniers chiffres (ce qui donne 11 * 100 possibilités). Mais si nous commençons avec 12 on ne peut choisir un nombre entre
00
et34
pour les deux derniers chiffres. Nous obtenons donc11 * 100 + 35
possibilités tout à fait.Voici une implémentation de cet algorithme (écrit en Python, mais d'une manière qui devrait être facile de port à C):
Je pense que vous avez mal interprété la partie. La règle est de diviser le nombre de plages avec le même nombre de chiffres, [1,999] devient ([1,9],[10,99],[100,999]), et ensuite, pour chaque segment de vous faire (haut-bas)*(longueur-1)/10, et les additionner. "Un traitement spécial pour la condition de fin" serait si, au lieu de [1,999] nous avons eu quelque chose comme [1,1234], où [1000,1234] ne rentre pas dans le modèle. C'est seulement cette dernière partie qui a besoin d'un traitement spécial.
Oui, je pensais (1,666) ou quelque chose, mais j'ai décidé d'aller le tout pour le tout et est allé trop loin.
OK, donc le code de telle manière qu'il nous est possible de le comparer à d'autres solutions 🙂
Maintenant que vous avez bien fourni le code et débogué, je suis de retirer mon downvote. Je pense toujours que la formulation récursive est plus simple, mais je suis d'accord que cela fonctionne. P. S. @drewk "attentes" sont peut-être mieux disant "donner la bonne réponse"
OriginalL'auteur
Je suggère d'adapter cet algorithme de base 2 en base 10:
Nombre de 1s dans le complément à deux représentations binaires des nombres entiers dans une gamme
L'résultant de l'algorithme est O(log N).
L'approche est d'écrire une simple fonction récursive
count(n)
qui compte le nombre de zéros de 1 àn
.L'observation essentielle est que si N se termine dans 9, par exemple:
Vous pouvez placer les nombres de 0 à N en 10 groupes de taille égale. Le groupe 0 est les nombres se terminant par 0. Le groupe 1 est le nombre se terminant par 1. Le groupe 2, les nombres se terminant par 2. Et ainsi de suite, tout le chemin à travers le groupe de 9, qui est tous les numéros se terminant par 9.
Chaque groupe à l'exception du groupe 0 contribue
count(N/10)
zéro chiffres au total, car aucun d'entre eux fin à zéro. Groupe 0 contribuecount(N/10)
(qui comprend tous les chiffres, sauf le dernier), plusN/10
(qui compte les zéros de la finale chiffres).Puisque nous sommes allant de 1 à N au lieu de 0 à N, cette logique s'effondre pour un seul chiffre N, donc nous avons juste la poignée que comme un cas particulier.
[mise à jour]
Ce que le diable, nous allons généraliser et de définir
count(n, d)
combien de fois le chiffred
apparaît parmi les nombres de 1 àn
.La laideur pour le cas
n < 10
vient de nouveau de la gamme allant de 1 àn
au lieu de 0 àn
... Pour tout à un seul chiffren
supérieure ou égale àd
, le nombre est 1, sauf lorsqued
est zéro.De la conversion de cette solution à un non-récursive boucle (a) est trivial, (b) inutiles, et (c) laissé comme exercice pour le lecteur.
[Mise à jour 2]
La finale
(d > 0)
terme vient aussi de la gamme allant de 1 àn
au lieu de 0 àn
. Lorsquen
se termine dans 9, combien de nombres entre 1 etn
inclusive ont dernier chiffred
? Eh bien, quandd
est égale à zéro, la réponse estn/10
; quandd
est non-nul, il est l'un plus que cela, puisqu'il comprend la valeurd
lui-même.Par exemple, si
n
est de 19 etd
est 0, il n'existe qu'un petit nombre se terminant par 0 (10). Mais sin
est de 19 etd
est de 2, il y a deux plus petits nombres se terminant par 2 (c'est à dire 2 et 12).Grâce à @Chan d'avoir signalé ce bug dans les commentaires; j'ai fixé dans le code.
J'ai posté une solution qui, je crois, quelque chose de semblable à ce que vous avez suggéré. Je suis aux prises avec la généralisation ma solution. Pouvez vous s'il vous plaît m'aider avec ça ? Merci
Avez-vous testé votre solution? Pour
n = 20
avecd = 2
, il y a 3 2 (2, 12, 20), mais votre solution ne produit que de 2.En effet, j'ai eu un bug à chaque fois que d est non nul. Fixe; merci.
Vous êtes les bienvenus 😉
OriginalL'auteur
Laisser
Z(n) = #zero digits in numbers 0 <= k < n
. Évidemment,Z(0) = 0
.Si
n = 10*k + r, 0 <= r <= 9
, tous les10*k
numéros de10*j + s, 0 <= j < k, 0 <= s <= 9
sont dans la gamme, chaque dixième dernier chiffre est 0, de sorte que lak
zéros, et chaque préfixej
(tous sauf le dernier chiffre) se produit une dizaine de fois, mais il ne faut pas compter 0, de sorte que le nombre de zéros dans les préfixes est10*(Z(k)-1)
.Le nombre de zéros dans le
r
numéros de10*k, ..., 10*k + (r-1)
estr*number of zeros in k + (r > 0 ? 1 : 0)
.Nous avons donc un
O(log n)
algorithme pour le calcul deZ(n)
Pour calculer le nombre pour une gamme arbitraire,
Oublié de soustraire le 0-préfixes, merci pour le heads-up.
Non, 344 est correct,
Prelude> length . filter (== '0') $ [0 .. 1233] >>= show
donne 344.Z(n)
compte le nombre de zéros dans0, 1, ..., n-1
, donc il doit être au moins à 1 pour tous lesn > 0
.C'est à partir de 0. Tous les droits.
OriginalL'auteur
La façon dont j'ai abordé ce problème:
numéros peut être dans la plage de 1 à N:
Donc, je me suis cassé la présente en plages comme ceci:
Maintenant pour toute la gamme 1 - N, je veux être en mesure de briser le nombre de ces plages et de l'utilisation de la logique ci-dessus pour calculer le nombre de zéros.
Test:
pour un nombre donné N:
Permet d'essayer de généraliser:
Je vais avoir quelques difficultés à procéder à partir d'ici, mais ce serait le travail.
OriginalL'auteur
OriginalL'auteur