ЯШ: Как считать буквами - PullRequest
0 голосов
/ 01 июня 2018

Я хочу иметь возможность считать в базе 26, но только с буквами алфавита.

Я могу охватить основы, такие как A + 1 = B и Z + 1 = AA, но я хочу, чтобы это работало дляочень длинные «числа», такие как AZZEBERBZZ

В настоящее время у меня есть следующий код в JavaScript

function getNextColumn(currentColumn) {
    currentColumn = currentColumn.toUpperCase();
    let lastLetterCode = currentColumn.charCodeAt(currentColumn.length - 1);

    if(lastLetterCode < 90) {
        return currentColumn.slice(0, -1) + String.fromCharCode(lastLetterCode + 1);
    } else {
        return currentColumn.slice(0, -1) + "A";
    }
}

Но проблема в том, что когда я нахожусь на AZ, он просто возвращается AAA вместо BA

Как я могу решить эту проблему?

ДОПОЛНИТЕЛЬНЫЙ КОНТЕКСТ:

Мне нужна функция getNextColumn, потому что я использую эту функцию для циклического перемещения пообъект, созданный из листа Excel, где столбцы учитываются в base26, но только с буквами и без цифр

Ответы [ 2 ]

0 голосов
/ 01 июня 2018

Обычно вы можете использовать одну функцию для получения числового значения, а другую - для преобразования числового значения обратно в требуемый формат.Это позволяет выполнять арифметические операции.

Для получения числа вы можете использовать parseInt с основанием 36 и коррекцией 9 (получим только значение букв) для значенияи Array#reduce для получения полного количества букв.

Коэффициент 26 равен длине алфавита, а буква, оставленная слева, имеет значение места, умноженное на 26.

Для возврата преобразованного значения вы можете использовать toString с основанием 36 для преобразования в искомые буквы.

function getValue(s) {
    return s.split('').reduce((r, a) => r * 26 + parseInt(a, 36) - 9, 0) - 1;
}

function setValue(n) {
    var result = '';
    do {
        result = (n % 26 + 10).toString(36) + result;
        n = Math.floor(n / 26) - 1;
    } while (n >= 0)
    return result.toUpperCase();
}

console.log(getValue('A'));              //    0
console.log(setValue(getValue('A')));
console.log(getValue('B'));              //    1
console.log(setValue(getValue('B')));
console.log(getValue('Z'));              //   25
console.log(setValue(getValue('Z')));
console.log(getValue('AA'));             //   26
console.log(setValue(getValue('AA')));
console.log(getValue('AZ'));             //   51
console.log(setValue(getValue('AZ')));
console.log(getValue('CZ'));             //  103
console.log(setValue(getValue('CZ')));
console.log(getValue('ZZ'));             //  701
console.log(setValue(getValue('ZZ')));
console.log(getValue('DXH'));            // 3335
console.log(setValue(getValue('DXH')));
.as-console-wrapper { max-height: 100% !important; top: 0; }
0 голосов
/ 01 июня 2018

Это идеальный кандидат для использования рекурсивной функции.

С помощью рекурсивной функции вам нужно определить базовую ситуацию и рекурсивную ситуацию.

Вы уже рассмотрели базовые ситуации, которыеВ этом случае возможны 2 ситуации:

  • Ввод заканчивается буквой, отличной от «Z»
  • Ввод «Z»

Во всехВ других случаях у вас возникает «рекурсивная ситуация», в которой ваш ввод:

  • Заканчивается на «Z»
  • и его длина превышает 1 букву

Для этой «рекурсивной ситуации» вы можете обрезать последний «Z» (потому что вам все равно нужно заменить его на «А»), а затем снова вызвать эту функцию, например:

function getNextColumn(currentColumn) {
    currentColumn = currentColumn.toUpperCase();
    let lastLetterCode = currentColumn.charCodeAt(currentColumn.length - 1);

    if(currentColumn === "Z"){
        return "AA";
    }

    if(lastLetterCode < 90) {
        return currentColumn.slice(0, -1) + String.fromCharCode(lastLetterCode + 1);
    }

    return getNextColumn(currentColumn.slice(0, -1)) + "A";
}
...