将十进制数转换为类似于excel-header的数字

时间:2010-12-15 07:13:28

标签: language-agnostic code-golf

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

我想不出任何不涉及loop-bruteforce的解决方案: - (

我期待一个函数/程序,它接受一个十进制数并返回一个字符串作为结果。

10 个答案:

答案 0 :(得分:7)

Haskell, 78 57 50 43 chars

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

其他条目不包括驱动程序,这会增加另外40个字符:

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

一种新的方法,使用懒惰的无限列表,以及Monads的力量!此外,使用sequence让我:),使用无限列表会让我:o

答案 1 :(得分:4)

如果仔细观察,excel表示符就像基数为26,但与基数26完全相同。

在基础-26 Z + 1 = AA

中的Excel转换Z + 1 = BA

该算法与十进制到基数为26的转换几乎相同,只需更改一次。 在base-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 Implementation

答案 2 :(得分:4)

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

答案 3 :(得分:3)

由于我不确定你要转换的基数和你想要的基数(你的标题暗示一个而你的问题相反),我将涵盖两者。

ZZ转换为701

的算法

首先要认识到我们在基数26中编码了一个数字,其中“数字”是A..Z。将计数器a设置为零并开始读取最右边的数字(最低有效数字)。从右到左进行,读取每个数字并将其“数字”转换为十进制数。将此乘以26 a 并将其添加到结果中。递增a并处理下一个数字。

701转换为ZZ

的算法

我们只是将数字计算为26的幂,就像转换为二进制时一样。只需取num%26,将其转换为A..Z“数字”并附加到转换后的数字(假设它是一个字符串),然后整数除以您的数字。重复,直到num为零。在此之后,将转换后的数字字符串反转为最重要的位。

编辑:正如您所指出的,一旦达到两位数的数字,我们实际上对所有非最低有效位都有27。只需在此处应用相同的算法,将任何“常量”递增1。 应该工作,但我自己没有尝试过。

重新编辑:对于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。

答案 4 :(得分:3)

在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

答案 5 :(得分:2)

Scala:63个字符

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

答案 6 :(得分:1)

Prolog, 109 123 bytes

从十进制数转换为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.

<击> 该代码对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).

答案 7 :(得分:1)

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)

答案 8 :(得分:1)

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;

答案 9 :(得分:0)

使用以下公式,您可以找出字符串中的最后一个字符:

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