Base Conversione Problema
Domanda
Sto cercando di convertire un intero in una stringa in questo momento, e sto avendo un problema.
ho ottenuto il codice scritto e di lavoro per la maggior parte, ma ha un piccolo difetto durante il trasporto al luogo successivo. E 'difficile da descrivere, quindi ti darò un esempio. Utilizzando base 26 con un set di caratteri che consiste dell'alfabeto minuscole:
0 = "a"
1 = "b"
2 = "c"
...
25 =
"z"
26 = "ba" (Questo deve essere uguale "aa")
Sembra saltare il carattere nel punto zero nel set di caratteri in certe situazioni.
La cosa che mi confonde è che vedo niente di sbagliato con il mio codice. Ho lavorato su questo per troppo tempo, e ancora non riesco a capirlo.
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);
Ho la sensazione che la funzione è inciampare sopra il modulo di tornare uno zero, ma ho lavorato su questo così tanto tempo, non riesco a capire come sta accadendo. Eventuali suggerimenti sono i benvenuti.
EDIT:. Il fatto che la stringa generata è little endian è irrilevante per la mia applicazione
Soluzione
Se ho capito bene ciò che si vuole (la numerazione utilizzata da Excel per le colonne, A, B, .. Z, AA, AB, ...) questo è una notazione basata in grado di rappresentare i numeri a partire dal 1. Il 26 le cifre hanno valori 1, 2, ... 26 e la base è 26. Così a ha valore 1, il valore Z 26, il valore di AA 27 ... Calcolo questa rappresentazione è molto simile alla reprentation normale è sufficiente per regolare la offset del 1 invece di 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;
}
Esecuzione con 1 2 26 27 52 53 676 677 702 703 dà
1 = A
2 = B
26 = Z
27 = AA
52 = AZ
53 = BA
676 = YZ
677 = ZA
702 = ZZ
703 = AAA
Altri suggerimenti
Il problema è che 'a' == 0.
In altre parole, 'aa' non è la risposta, perché è veramente 00. 'ba' è la risposta corretta perché b = '1', in modo che il 10 lo rende in base 26, che è 26 in decimale.
Il codice è corretto, basta sembra di essere malinteso.
Credo che si dovrebbe fare a = 1 e z = 0 in modo da avere abc ... z proprio come in decimale 1234 ... 90
Confronto al sistema decimale: 9 è seguito da 10 e non da 01
Per ottenere la soluzione Aprogrammers per la compilazione sul mio sistema (sto usando gcc version 4.6.1 (Ubuntu / Linaro 4.6.1-9ubuntu3) avevo bisogno di aggiungere intestazioni; #include <climits> #include<cstdlib>