Как реализовать метод буквенного номера по числу?

Есть задание:
Задание

Колонки электронных таблиц (например Excel) имеют буквенную нумерацию в виде больших букв латинского алфавита (последовательно, слева направо):
A, B, ..., Y, Z, AA, AB, ..., AY, AZ, BA, BB, ... и т.д.

В то же время каждая колонка имеет порядковый номер: A - 1; B - 2; ... ; Y - 25; Z - 26; AA - 27; AB - 28; ... и т.д.

Написать класс, который содержит следующие три метода:

1) метод определения порядкового номера колонки по ее буквенному номеру
[ public static int chars2digits(String number): A => 1; B => 2; ...; Z => 26; AA => 27; AB => 28; ... ];

2) метод определения буквенного номера колонки по ее порядковому номеру
[ public static String digits2chars(int number): 1 => A; 2 => B; ...; 26 => Z; 27 ==> AA; 28 ==> AB; ... ];

Составить и реализовать алгоритм первой функции у меня получилось, вот он:
public static int chars2digits(String number) {
        int res = 0;
        for (int i = 0, j = number.length() - 1; i < number.length(); i++, j--) {
            res += (number.charAt(j)-64)*Math.pow(26, i);
        }
        return res;
    }

А вот со второй у меня явные проблемы, не могу даже понять от чего отталкиваться и в каком направлении думать.
Реализовать алгоритм смогу, только как он должен выглядеть - не знаю. Помогите идеями.
  • Вопрос задан
  • 1006 просмотров
Пригласить эксперта
Ответы на вопрос 2
LaRN
@LaRN
Senior Developer
Тут алгоритм похож на перевод числа из N-й системы исчисления в M-ю.

Тут N = 10, а M = 26
Например, на входе число 153
b = 0
a = 153

Шаг 1. (последняя цифра числа)
b = mod(a/26) = 23 (153/26) - остаток от деления
a = div(a/26) = 5 (153/26) - целая часть

23 - это символ с кодом 23 + 64 = W

Шаг 2. (пред-последняя цифра числа)
b = mod(a/26) = 5 (5/26) - остаток от деления
a = div(a/26) = 0 (5/26) - целая часть

5 - это символ с кодом 23 + 5 = E

Шаг 3. (пред-пред-последняя цифра числа)
a = 0 - выходим

В итоге число EW.
Ответ написан
Комментировать
@Mercury13
Программист на «си с крестами» и не только
Вот мой действующий код на «Си с крестами». Индексы — ВНИМАНИЕ — начинаются с нуля. Сумеете перевести на Яву, и из второго оставить одни буквы? Первое действует для любой длины, второе — для длины до 3 символов, присущей Excel’ю.

std::wstring xl::colNameW(
        size_t aIndex)
{
    wchar_t q[21];  // more than enough even for 64-bit system :)
    wchar_t* ptr = q + 20;
    *ptr = 0;   // debug

    // Getting size
    size_t n = 1;
    unsigned long long pw = 26;
    while (aIndex>=pw && n<20)
    {
        aIndex -= static_cast<size_t>(pw);
        pw *= 26;
        ++n;
    }

    FOR_S(i, 0, n)  // макрос, означающий for (size_t i = 0; i < n; ++i)
    {
        *(--ptr) = static_cast<wchar_t>(L'A' + (aIndex % 26));
        aIndex /= 26;
    }
    return std::wstring(ptr, n);
}

namespace {

    bool isCap(const char* x, const char* aEnd)
    {
        return (x != aEnd && *x >= 'A' && *x <= 'Z');
    }

    bool isDig(const char* x, const char* aEnd)
    {
        return (x != aEnd && *x >= '0' && *x <= '9');
    }

}   // anon namespace


xl::CellCoords xl::parseCellCoords(
        const char* aStart, const char* aEnd)
{
    enum {
        AA = 26,
        AAA = 26 + 26 * 26
    };
    xl::CellCoords r;
    // Letter
    r.col = 0;
    if (!isCap(aStart, aEnd))
        return CellCoords::bad();
    r.col = *(aStart++) - 'A';
    if (isCap(aStart, aEnd)) {
        r.col = (r.col * 26) + *(aStart++) - 'A';
        if (isCap(aStart, aEnd)) {
            r.col = AAA + (r.col * 26) + *(aStart++) - 'A';
        } else {
            r.col += AA;
        }
    }
    // Number
    r.row = 0;
    while (isDig(aStart, aEnd)) {
        size_t r0 = r.row;
        r.row = r.row * 10 + *(aStart++) - '0';
        if (r.row < r0)
            return CellCoords::bad();
    }
    if (r.row == 0 || aStart != aEnd)
        return CellCoords::bad();
    --r.row;
    return r;
}


Принцип действия перевода цифра → буква.
Находим, сколько букв в нашей колонке. Допустим, три. Вычитаем из цифры номер колонки AAA (т.е. 26 + 26·26, если нумеровать с нуля, и 1 + 26 + 26·26 — если с единицы), и оставшееся переводим в 26-ичную систему счисления (A=0, B=1, C=2…).

Принцип действия перевода буква → цифра аналогичен. Находим количество букв. Если их три, то переводим из 26-ичной системы счисления в цифру и прибавляем номер колонки AAA.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы
Bell Integrator Ульяновск
До 400 000 ₽
Bell Integrator Ижевск
До 400 000 ₽
Bell Integrator Хабаровск
До 400 000 ₽