Convert decimal number to excel-header-like number

2019-04-19 11:56发布

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

I cannot think of any solution that does not involve loop-bruteforce :-(

I expect a function/program, that accepts a decimal number and returns a string as a result.

10条回答
祖国的老花朵
2楼-- · 2019-04-19 12:17

Python, 44 chars

Oh c'mon, we can do better than lengths of 100+ :

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

Testing:

>>> 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
查看更多
Viruses.
3楼-- · 2019-04-19 12:18

If you look carefully the excel representation is like base 26 number but not exactly same as base 26.

In Excel conversion Z + 1 = AA while in base-26 Z + 1 = BA

The algorithm is almost same as decimal to base-26 conversion with just once change. In base-26, we do a recursive call by passing it the quotient, but here we pass it 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 Implementation

查看更多
Viruses.
4楼-- · 2019-04-19 12:19

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)
查看更多
干净又极端
5楼-- · 2019-04-19 12:23

Since I am not sure what base you're converting from and what base you want (your title suggests one and your question the opposite), I'll cover both.

Algorithm for converting ZZ to 701

First recognize that we have a number encoded in base 26, where the "digits" are A..Z. Set a counter a to zero and start reading the number at the rightmost (least significant digit). Progressing from right to left, read each number and convert its "digit" to a decimal number. Multiply this by 26a and add this to the result. Increment a and process the next digit.

Algorithm for converting 701 to ZZ

We simply factor the number into powers of 26, much like we do when converting to binary. Simply take num%26, convert it to A..Z "digits" and append to the converted number (assuming it's a string), then integer-divide your number. Repeat until num is zero. After this, reverse the converted number string to have the most significant bit first.

Edit: As you point out, once two-digit numbers are reached we actually have base 27 for all non-least-significant bits. Simply apply the same algorithms here, incrementing any "constants" by one. Should work, but I haven't tried it myself.

Re-edit: For the ZZ->701 case, don't increment the base exponent. Do however keep in mind that A no longer is 0 (but 1) and so forth.

Explanation of why this is not a base 26 conversion

Let's start by looking at the real base 26 positional system. (Rather, look as base 4 since it's less numbers). The following is true (assuming 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

And so forth... notice that AA is 0 rather than 4 as it would be in Excel notation. Hence, Excel notation is not base 26.

查看更多
男人必须洒脱
6楼-- · 2019-04-19 12:24

Scala: 63 chars

def c(n:Int):String=(if(n<26)""else c(n/26-1))+(65+n%26).toChar
查看更多
对你真心纯属浪费
7楼-- · 2019-04-19 12:25

Prolog, 109 123 bytes

Convert from decimal number to Excel string:

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.

That code does not work for c(27, N), which yields N='BB'

This one works fine:

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,!.

Tests:

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


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

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

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

Converts from Excel string to decimal number (87 bytes):

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).
查看更多
登录 后发表回答