Основная проблема преобразования - PullRequest
2 голосов
/ 19 февраля 2010

Я сейчас пытаюсь преобразовать целое число в строку, и у меня возникла проблема.

Я получил код, написанный и работающий по большей части, но у него есть небольшой недостаток при переносе на следующее место. Это сложно описать, поэтому я приведу пример. Использование базы 26 с набором символов, состоящим из строчного алфавита:

0 = "а"
1 = "b"
2 = "с"

...

25 = "z"
26 = "ba" (это должно быть равно "aa")

В некоторых ситуациях кажется, что символ пропускается на нулевом месте в наборе символов.

Меня смущает то, что я не вижу ничего плохого в своем коде. Я работаю над этим слишком долго и до сих пор не могу понять.

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);

У меня такое ощущение, что функция срабатывает по модулю, возвращая ноль, но я так долго работал над этим, я не могу понять, как это происходит. Любые предложения приветствуются.

РЕДАКТИРОВАТЬ: факт, что сгенерированная строка имеет младший порядок, не имеет значения для моего приложения.

Ответы [ 4 ]

4 голосов
/ 19 февраля 2010

Если я правильно понимаю, что вы хотите (нумерация, используемая Excel для столбцов, A, B, .. Z, AA, AB, ...), это основанная нотация, способная представлять числа, начиная с 1. 26 цифры имеют значения 1, 2, ... 26, а основание - 26. Таким образом, A имеет значение 1, Z - значение 26, значение AA - 27 ... Вычисление этого представления очень похоже на обычное представление, которое вам просто нужно настроить для смещение 1 вместо 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;
}

Бег с 1 2 26 27 52 53 676 677 702 703 т

1 = A
2 = B
26 = Z
27 = AA
52 = AZ
53 = BA
676 = YZ
677 = ZA
702 = ZZ
703 = AAA
4 голосов
/ 19 февраля 2010

Ваша проблема в том, что 'a' == 0.

Другими словами, «aa» не является ответом, потому что это действительно 00. «ba» является правильным ответом, потому что b = «1», так что это делает его 10 в базе 26, что составляет 26 в десятичной дроби.

Ваш код верен, вы, похоже, неправильно его понимаете.

0 голосов
/ 10 апреля 2012

Чтобы компилировать решение Aprogrammers на моей системе (я использую gcc версии 4.6.1 (Ubuntu / Linaro 4.6.1-9ubuntu3), мне нужно было добавить заголовки; #include <climits> #include<cstdlib>

0 голосов
/ 19 февраля 2010

Я думаю, вы должны сделать a = 1 и z = 0, чтобы у вас было abc ... z, как в десятичном виде 1234 ... 90

Сравните это с десятичной системой: за 9 следует 10, а не 01!

...