Language agnostic 将十进制数字转换为类似excel标题的数字
我想不出任何不涉及循环暴力的解决方案:-(Language agnostic 将十进制数字转换为类似excel标题的数字,language-agnostic,code-golf,Language Agnostic,Code Golf,我想不出任何不涉及循环暴力的解决方案:-( 我需要一个函数/程序,它接受一个十进制数并返回一个字符串。如果您仔细查看,excel表示法类似于base 26 number,但与base 26不完全相同 在Excel转换中Z+1=AA而在base-26中Z+1=BA 该算法几乎与十进制到基数-26的转换相同,只需更改一次。 在base-26中,我们通过向它传递商来进行递归调用,但在这里我们传递商-1: 0 = A 1 = B ... 25 = Z 26 = AA 27 = AB ... 701 =
我需要一个函数/程序,它接受一个十进制数并返回一个字符串。如果您仔细查看,excel表示法类似于base 26 number,但与base 26不完全相同 在Excel转换中
Z+1=AA
而在base-26中Z+1=BA
该算法几乎与十进制到基数-26的转换相同,只需更改一次。
在base-26中,我们通过向它传递商来进行递归调用,但在这里我们传递商-1
:
0 = A
1 = B
...
25 = Z
26 = AA
27 = AB
...
701 = ZZ
702 = AAA
函数decimalToExcel(num)
//递归的基本条件。
如果num<26
打印“A”+num
其他的
商=num/26;
提醒=num%26;
//递归调用。
分贝(商-1);
decimalToExcel(提醒);
如果结束
端函数
因为我不确定你是从哪个基础转换过来的,也不确定你想要什么基础(你的标题暗示了一个基础,而你的问题正好相反),所以我将介绍这两个方面
将ZZ
转换为701
首先认识到我们有一个编码在基数26中的数字,其中“数字”是a..Z
。将计数器a
设置为零,然后开始读取最右边的数字(最低有效数字)。从右到左,读取每个数字并转换其“数字”一个十进制数。将其乘以26a
并将其加到结果中。递增a
并处理下一个数字
将701
转换为ZZ
我们只是简单地将数字分解为26的幂,就像我们在转换为二进制时所做的那样。只需取num%26
,将其转换为A..Z
“数字”,并附加到转换后的数字上(假设它是一个字符串),然后整数除以数字。重复此操作直到num
为零。然后,反转转换后的数字字符串,使其首先具有最高有效位
编辑:正如您所指出的,一旦达到两位数,所有非最低有效位的基数实际上为27。只需在此处应用相同的算法,将任何“常量”增加1。应该可以,但我自己没有尝试过
重新编辑:对于ZZ->701
情况,不要增加基本指数。但是请记住A
不再是0(而是1),以此类推
解释为什么这不是基数26转换
让我们从实际的base 26位置系统开始(而是以base 4为基础,因为它的数字较少)。以下是正确的(假设A=0):
等等……请注意,AA
是0,而不是Excel表示法中的4。因此,Excel表示法不是以26为基数。使用以下公式,您可以计算出字符串中的最后一个字符:
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
使用这个函数,我们可以生成一个递归函数(我不认为它很强大)
或者……诸如此类。我真的很累了,也许我应该停止回答问题去睡觉了:pHaskell,78 57 50 43 chars
其他条目不包括驱动程序,这又增加了40个字符:
o=map(['A'..'Z']:)$[]:o
e=(!!)$o>>=sequence
一种新的方法,使用一个懒惰的、无限的列表和单子的力量!此外,使用序列使我:)
,使用无限列表使我:o
Prolog,109 123字节
从十进制数转换为Excel字符串:
从Excel字符串转换为十进制数(87字节):
在Excel VBA中。。。显而易见的选择:)
或者获取工作表第一行中的列号(因为我们在Excel中,所以更有意义…)
或者更好:56个字符
Python,44个字符
哦,拜托,我们可以比100+的长度做得更好:
Sub a()
Set O = Range("A1:AA1")
O.Formula = "=Column()"
End Sub
测试:
X=lambda n:~n and X(n/26-1)+chr(65+n%26)or''
斯卡拉:63个字符
defc(n:Int):字符串=(if(nF#):166 137
让rec c x=如果x<26那么[(char)((int'A')+x)]else List.append(c(x/26-1))(c(x%26))
设sx=新字符串(cx |>List.toArray)
PHP:至少59和33个字符。
听起来像是base10到base26的转换问题…@deceze:听起来像,但不是:-)@deceze:因为在数字AA中,两个字符实际上并不意味着相同的数字。它们代表不同的数字。第一个字符相当于1,第二个字符相当于0;-)@虫族:你想要AA-->26
转换还是26-->AA
?Uhm可能重复,我不同意这是一个基数为26的数字。将1添加到任何数字后,无法获得由相同数字组成的总数<代码>Z+1==AA
。这在“常规”基地是不可能的。@zerkms9+1=10
Z+B=AA
,其中(base26)B等于(base10)1Z+1
是胡说八道,因为这是混合基数。你肯定会期望Z+B(1)=BA(10)?@deceze:因为“真实”基数26中的A=0,AA是0。或者更确切地说是00。@Gareth:我希望在数字之前加零(0==A)不会改变它的实际值。但对于类似excel的表示法来说是不正确的。不,这将转换为实基数26,而不是奇怪的excel基数。是的,我现在明白了。我会更加小心:)即使这个答案不是100%正确,我也不认为它值得被删除(+1)你可以使用fromnum
而不是应该更短的chr。@gusbro:是的,它是。将它们添加到示例中
o=map(['A'..'Z']:)$[]:o
e=(!!)$o>>=sequence
main=interact$unlines.map(e.read).lines
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(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'
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).
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
Sub a()
For Each O In Range("A1:AA1")
O.Value = O.Column - 1
Next
End Sub
Sub a()
Set O = Range("A1:AA1")
O.Formula = "=Column()"
End Sub
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
def c(n:Int):String=(if(n<26)""else c(n/26-1))+(65+n%26).toChar
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)
<?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;