M
M
Mykhailo Tkachenko2018-03-21 14:00:56
Java
Mykhailo Tkachenko, 2018-03-21 14:00:56

How to implement the letter number by number method?

There is a task:

Exercise

Колонки электронных таблиц (например 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; ... ];

I succeeded in compiling and implementing the algorithm of the first function, here it is:
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;
    }

But with the second I have obvious problems, I can’t even understand what to build on and in what direction to think.
I can implement the algorithm, but I don’t know how it should look like. Help with ideas.

Answer the question

In order to leave comments, you need to log in

2 answer(s)
R
Ruslan., 2018-03-21
@LaRN

Here the algorithm is similar to the translation of a number from the N-th system of calculus to the M-th.
Here N = 10, and M = 26
For example, the input number is 153
b = 0
a = 153
Step 1. (last digit of the number)
b = mod(a/26) = 23 (153/26) - the remainder of the division
a = div(a/26) = 5 (153/26) - the integer part of
23 is the character with the code 23 + 64 = W
Step 2. (pre-last digit of the number)
b = mod(a/26) = 5 (5/ 26) - remainder of division
a = div(a/26) = 0 (5/26) - integer part
5 is a character with code 23 + 5 = E
Step 3. (before-before-last digit of the number)
a = 0 - exit
As a result, the number of EW.

M
Mercury13, 2018-03-21
@Mercury13

Here is my current code in "C with crosses". Indexes - WARNING - start from zero. Will you be able to translate into Java, and leave only letters from the second? The first is valid for any length, the second - for the length of up to 3 characters inherent in Excel'yu.

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

The principle of the translation number → letter.
Find how many letters are in our column. Let's say three. We subtract the number of the AAA column from the figure (i.e. 26 + 26 26, if numbering from zero, and 1 + 26 + 26 26 - if from one), and translate the rest into the 26-number system (A=0, B=1, C=2…).
The principle of operation of the translation letter → number is similar. Find the number of letters. If there are three of them, then we translate from the 26-th number system into a number and add the AAA column number.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question