2010-07-28 9 views
5

Mon petit frère de 15 ans commence la programmation, et il a écrit un petit programme qui produit toute la combinaison de lettres et de chiffres de six chiffres ou moins. Son code était une boucle pour sextuple imbriquée qui mettait à jour les éléments d'un tableau de char à six niveaux. Il avait l'air mal, mais était certainement rapide! Je lui ai montré comment faire un simple comptage, et convertir ces nombres en base 36.Comment puis-je compter dans une base de nombres différente en C++?

Le plus gros problème est que mon code était tellement plus lent que le sien, à cause de la division que je faisais. Y a-t-il un moyen que je peux simplement supposer la base 36 et produire un compte de 1 à 36^6?

Idéalement, je cherche à faire quelque chose comme

[base 36] 
for(int i = 0; i < 1000000; i++) 
    SaveForLaterFileOutput(i); 
+6

Vous êtes source de confusion avec la présentation. Le comptage pur n'est pas un concept qui peut recevoir une base. Une version refactorisée de la solution de votre frère pourrait être le meilleur des deux! –

+0

Il n'y a pas de construction base36 intégrée dans la langue. Cependant, vous n'avez pas besoin de division pour faire ce que vous voulez. – driis

Répondre

3

Essayez ceci:

char buffer[1024]; 
for(int i = 0; i < 1000000; i++) 
     cout << itoa (i, buffer, 36); 

Ici, il est sans itoa (si vous ne l'avez pas)

cout << setbase (36); 
for(int i = 0; i < 1000000; i++) 
     cout << i << endl; 
cout << setbase (10); // if you intend to keep using cout 

+2

'itoa' n'est pas dans la norme et toutes les bibliothèques C++ ne l'incluent pas. –

+0

C'est sûr que c'est un truc. Merci. – Jeffrey

+0

Mis à jour pour avoir une réponse sans itoa (merci @Konrad Rudolph) –

1

pour convertir un nombre en base 36: faire un accumulateur et commencer à partir d'un degré suffisamment élevé, par exemple 36^6. Si l'accumulateur plus ce nombre est inférieur à votre numéro, ajoutez-le à l'accumulateur et répétez pour le même degré (le compte de ceci est la valeur numérique), s'il est plus grand, jetez-le. Répétez l'opération pour les degrés inférieurs jusqu'à atteindre 36^0. Gardez une trace du compte pour chaque degré, et c'est votre numéro dans la base 36.

pour l'imprimer de manière significative, faire autre chose.

1

Tous les chiffres utilisés dans les calculs sont en base 2 Tout autre numéro que vous voyez est juste une illusion sur la façon dont il est imprimé. Par conséquent, votre SaveForLaterOutput est inutile.

La fonction de bibliothèque itoa() (qui se traduit par "entier en ASCII") (ces jours-ci il a été remplacé par la fonction sécurisée _itoa_s()) vous permet de spécifier la base lors de la préparation de la sortie.

+0

Il n'y a pas de "2" en binaire, donc techniquement, tous les calculs sont en base 10 binaire (à ne pas confondre avec le nombre dix que nous aimons tant). – fredoverflow

+0

Il y a seulement 10 types de personnes dans le monde: Ceux qui comprennent binaire et ceux qui ne le font pas. –

+0

Il y a 10 sortes de personnes: ceux qui comprennent ternaire, ceux qui ne le font pas et ceux qui le prennent pour binaires;) –

2

Votre frère peut mettre à jour son tableau de 6 éléments sans avoir besoin de 6 boucles imbriquées. En modifiant la fonction increment ci-dessous, vous pouvez compter en tout vous « base » choisissez:

#include <algorithm> 
#include <iostream> 

#define NUM_CHARS 6 

// assuming ASCII 
// advances through a chosen sequence 0 .. 9, a .. z 
// or returns -1 on overflow 
char increment(char &c) { 
    if (c == 'z') return -1; 
    if (c == '9') { c = 'a'; return c; } 
    return ++c; 
} 

int main() { 
    char source[NUM_CHARS+1] = {0}; 
    std::fill_n(&source[0], NUM_CHARS, '0'); 
    while (true) { 
     std::cout << source << "\n"; 
     int idx = NUM_CHARS; 
     // increment and test for overflow 
     while (increment(source[--idx]) == -1) { 
      // overflow occurred: carry the 1 
      source[idx] = '0'; 
      if (idx == 0) return 0; 
     } 
    } 
} 

Je n'ai pas pris la peine avec la partie « ou moins » du problème: mais vous l'avez fait avec 6 boucles travaillera probablement avec cette technique aussi. Strictement parlant, il s'agit d'énumérer des combinaisons, ce qui est presque mais pas tout à fait la même chose que de compter.