Question

J'essaie actuellement de convertir un entier en chaîne et j'ai un problème.

J'ai écrit le code et il fonctionne pour la plupart, mais il présente un petit défaut lors du passage à l'endroit suivant.C'est difficile à décrire, alors je vais vous donner un exemple.En utilisant la base 26 avec un jeu de caractères composé de l'alphabet minuscule :

0 = "un"
1 = "b"
2 = "c"

...

25 = "z"
26 = "ba" (cela devrait être égal à "aa")

Il semble sauter le caractère à la place zéro dans le jeu de caractères dans certaines situations.

Ce qui me déroute, c'est que je ne vois rien de mal dans mon code.Je travaille là-dessus depuis trop longtemps maintenant et je n'arrive toujours pas à comprendre.

char* charset = (char*)"abcdefghijklmnopqrstuvwxyz";
int charsetLength = strlen(charset);

unsigned long long num = 5678; // Some random number, it doesn't matter
std::string key

do
{
    unsigned int remainder = (num % charsetLength);
    num /= charsetLength;

    key.insert(key.begin(), charset[remainder]);

} while(num);

J'ai le sentiment que la fonction trébuche sur le modulo renvoyant un zéro, mais je travaille là-dessus depuis si longtemps que je n'arrive pas à comprendre comment cela se passe.Toutes les suggestions sont les bienvenues.

MODIFIER:Le fait que la chaîne générée soit en Little Endian n'a pas d'importance pour mon application.

Était-ce utile?

La solution

Si je comprends bien ce que vous voulez (la numérotation utilisée par Excel pour les colonnes, A, B, .. Z, AA, AB, ...) ceci est une notation basée en mesure de représenter des nombres à partir de 1. Le 26 chiffres ont des valeurs 1, 2, ... 26 et la base est 26. Ainsi, une valeur a 1, valeur Z 26, la valeur AA 27 ... le calcul de cette représentation est très similaire à la normale reprentation vous avez juste besoin de régler la décalage de 1 au lieu de 0.

#include <string>
#include <iostream>
#include <climits>

std::string base26(unsigned long v)
{
    char const digits[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    size_t const base = sizeof(digits) - 1;
    char result[sizeof(unsigned long)*CHAR_BIT + 1];
    char* current = result + sizeof(result);
    *--current = '\0';

    while (v != 0) {
        v--;
        *--current = digits[v % base];
        v /= base;
    }
    return current;
}

// for testing
#include <cstdlib>

int main(int argc, char* argv[])
{
    for (int i = 1; i < argc; ++i) {
        unsigned long value = std::strtol(argv[i], 0, 0);
        std::cout << value << " = " << base26(value) << '\n';
    }
    return 0;
}

Fonctionnement avec 2 26 27 1 52 53 676 677 702 703 donne

1 = A
2 = B
26 = Z
27 = AA
52 = AZ
53 = BA
676 = YZ
677 = ZA
702 = ZZ
703 = AAA

Autres conseils

Votre problème est que 'a' == 0.

En d’autres termes, « aa » n’est pas la réponse, car il s’agit en réalité de 00.'ba' est la bonne réponse car b = '1', ce qui fait 10 en base 26, soit 26 en décimal.

Votre code est correct, vous semblez simplement ne pas le comprendre.

Je pense que vous devriez faire un = 1 et z = 0 donc vous avez abc ... z comme en décimal 1234 ... 90

Comparer à système décimal: 9 est suivie par 10 et non par 01

Pour obtenir la solution Aprogrammers pour compiler sur mon système (j'utilise la version gcc 4.6.1 (Ubuntu / Linaro 4.6.1-9ubuntu3) Je avais besoin d'ajouter des en-têtes; #include <climits> #include<cstdlib>

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top