Преобразуйте десятичное число в число, соответствующее заголовку excel-header

0 = A
1 = B
...
25 = Z
26 = AA
27 = AB
...
701 = ZZ
702 = AAA

Я не могу думать о каком-либо решении, которое не включает loop-bruteforce: - (

Я ожидаю функцию/программу, которая принимает десятичное число и возвращает в результате строку.

Ответ 1

Haskell, 78 57 50 43 символа

o=map(['A'..'Z']:)$[]:o
e=(!!)$o>>=sequence

Другие записи не учитывают драйвер, который добавляет еще 40 символов:

main=interact$unlines.map(e.read).lines

Новый подход, используя ленивый, бесконечный список и мощь Монад! И кроме того, использование sequence делает меня :), использование бесконечных списков делает меня :o

Ответ 2

Если вы посмотрите внимательно, то выражение excel похоже на число 26, но не точно так же, как и на базе 26.

Преобразование Excel Z + 1 = AA в то время как в base-26 Z + 1 = BA

Алгоритм почти такой же, как десятичное преобразование base-26, с однократным изменением. В базе 26 мы делаем рекурсивный вызов, передавая ему quotient, но здесь мы передаем его quotient-1:

function decimalToExcel(num)

        // base condition of recursion.
        if num < 26
                print 'A' + num 

        else                     
                quotient = num / 26;
                reminder = num % 26;

                // recursive calls.
                decimalToExcel(quotient - 1);
                decimalToExcel(reminder);
        end-if                       
end-function 

Реализация Java

Ответ 3

Python, 44 символа

О, давай, мы можем сделать лучше, чем длины 100+:

X=lambda n:~n and X(n/26-1)+chr(65+n%26)or''

Тестирование:

>>> for i in 0, 1, 25, 26, 27, 700, 701, 702:
...     print i,'=',X(i)
...     
0 = A
1 = B
25 = Z
26 = AA
27 = AB
700 = ZY
701 = ZZ
702 = AAA

Ответ 4

Так как я не уверен, какую базу вы переводите и какую базу вы хотите (ваш заголовок предлагает один и ваш вопрос наоборот), я расскажу обо всех.

Алгоритм преобразования ZZ в 701

Сначала узнаем, что у нас есть номер, закодированный в базе 26, где "цифры" A..Z. Установите счетчик a на ноль и начните считывать номер справа (наименьшая значащая цифра). Прогрессируя справа налево, читайте каждое число и преобразуйте его "цифру" в десятичное число. Умножьте это на 26 a и добавьте это в результат. Приращение a и обработать следующую цифру.

Алгоритм преобразования 701 в ZZ

Мы просто умножаем число на степени 26, как и при преобразовании в двоичный. Просто возьмите num%26, преобразуйте его в A..Z "цифры" и добавьте к преобразованному числу (при условии, что это строка), затем integer-divide your number. Повторяйте до тех пор, пока num не станет равным нулю. После этого измените преобразованную числовую строку на самый старший бит.

Изменить: Как вы указываете, после достижения двухзначных чисел у нас фактически есть база 27 для всех наименее значимых бит. Просто примените те же алгоритмы здесь, увеличивая любые "константы" на единицу. Должен работать, но я сам не пробовал.

Перередактировать: Для случая ZZ->701 не увеличивайте базовый показатель экспоненты. Однако имейте в виду, что a больше не равно 0 (но 1) и т.д.

Объяснение, почему это не преобразование базы 26

Пусть начнется, посмотрев на реальную базовую систему 26. (Скорее, посмотрите как основание 4, так как это меньше чисел). Следующее верно (при условии, что A = 0):

 A = AA = A * 4^1 + A * 4^0 = 0 * 4^1 + 0 * 4^0 = 0
 B = AB = A * 4^1 + B * 4^0 = 0 * 4^1 + 1 * 4^0 = 1
 C = AC = A * 4^1 + C * 4^0 = 0 * 4^1 + 2 * 4^0 = 2
 D = AD = A * 4^1 + D * 4^0 = 0 * 4^1 + 3 * 4^0 = 3
     BA = B * 4^0 + A * 4^0 = 1 * 4^1 + 0 * 4^0 = 4

И так далее... обратите внимание, что AA равен 0, а не 4, как это было бы в нотации Excel. Следовательно, примечание Excel не является базой 26.

Ответ 5

В Excel VBA... очевидный выбор:)

Sub a()

  For Each O In Range("A1:AA1")
    k = O.Address()
    Debug.Print Mid(k, 2, Len(k) - 3); "="; O.Column - 1
  Next

End Sub

Или для получения номера столбца в первой строке рабочего листа (что имеет больше смысла, поскольку мы находимся в Excel...)

Sub a()

  For Each O In Range("A1:AA1")
    O.Value = O.Column - 1
  Next

End Sub

Или еще лучше:

56 символов

Sub a()
  Set O = Range("A1:AA1")
  O.Formula = "=Column()"
End Sub

Ответ 6

Scala: 63 символа

def c(n:Int):String=(if(n<26)""else c(n/26-1))+(65+n%26).toChar

Ответ 7

Пролог, 109 123 байта

Преобразовать из десятичного числа в строку Excel:

c(D,E):- d(D,X),atom_codes(E,X).
d(D,[E]):-D<26,E is D+65,!.
d(D,[O|M]):-N is D//27,d(N,M),O is 65+D rem 26.

Забастовкa > Этот код не работает для c (27, N), что дает N = 'BB'

Это хорошо работает:

c(D,E):-c(D,26,[],X),atom_codes(E,X).
c(D,B,T,M):-(D<B->M-S=[O|T]-B;(S=26,N is D//S,c(N,27,[O|T],M))),O is 91-S+D rem B,!.

Тесты:

?- c(0, N).
N = 'A'.


?- c(27, N).
N = 'AB'.

?- c(701, N).
N = 'ZZ'.

?- c(702, N).
N = 'AAA'

Преобразует из строки Excel в десятичное число (87 байтов):

x(E,D):-x(E,0,D).
x([C],X,N):-N is X+C-65,!.
x([C|T],X,N):-Y is (X+C-64)*26,x(T,Y,N).

Ответ 8

F #: 166 137

let rec c x  = if x < 26 then [(char) ((int 'A') + x)] else List.append (c (x/26-1)) (c (x%26))
let s x = new string (c x |> List.toArray)

Ответ 9

PHP: не менее 59 и 33 символа.

<?for($a=NUM+1;$a>=1;$a=$a/26)$c=chr(--$a%26+65).$c;echo$c;

Или кратчайшая версия:

<?for($a=A;$i++<NUM;++$a);echo$a;

Ответ 10

Используя следующую формулу, вы можете определить последний символ в строке:

transform(int num)
    return (char)num + 47; // Transform int to ascii alphabetic char. 47 might not be right.

char lastChar(int num)
{
    return transform(num % 26);
}

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

string getExcelHeader(int decimal)
{
    if (decimal > 26)
        return getExcelHeader(decimal / 26) + transform(decimal % 26);
    else
        return transform(decimal);
}

Или что-то в этом роде. Я действительно устал, может, мне стоит перестать отвечать на вопросы и ложиться спать: P