【题目】
一个char类型的数组chs,其中所有的字符都不同。
例如,chs = [‘A’, ‘B’, ‘C’, … ‘Z’],则字符串与整数的对应关系如下:
A,B,C…Z,AA,AB…AZ,BA,BB…ZZ,AAA…ZZZ,AAAA…
1,2,3…26,27,28…52,53,54…702,703…18278,18279
例如,chs = [‘A,’ ‘B’, ‘C’],则字符串与整数的对应关系如下:
A,B,C,AA,AB…CC,AAA…CCC,AAAA…
1,2,3, 4, 5 … 12, 14 …39,40
给定一个数组chs,实现根据对应关系完成字符串与整数相互转换的两个函数。
【基本思路】
这道题类似于10进制数与k进制数相互转换,不同的是,这次的k进制数每一位上不能取0,取值的范围是[1, k],我们把它叫做k伪进制数。
从数字到字符串。以chs = [‘A’, ‘B’, ‘C’],n = 72为例子描述该过程:
chs的长度为3,所以这是一个3伪进制,从低位到高位依次为1,3,9,27,81…
从1开始减,72减1剩余71;71减3剩余68;68减9剩余59;59减27剩余32;32减81,不够减。此时就知道想要表达十进制数的72,只需要使用3伪进制的前4位,也就是27,9,3,1。换句话说,既然k伪进制中每个位上的值都不能等于0,就从低位到高位把每个位置的都值都先减去1,看这个数到底需要前几位。
步骤2剩余的数是32,同时前四位的值各用了一遍。接下来看32最多可以用几个27,最多用1个,加上之前使用的一个,一个要用两个27,所以该位置上应该填 ‘B’。32%27的结果是5,然后看5能用几个9,一个也用不了,所以该位置应该填 ‘A’。再看5能用几个3,能用一个,所以该位置填 ‘B’。5%3的结果是2,再看2能用几个1,能用两个,所以该位置应该填 ‘C’。所以结果是 “BABC”
总结一下,就是先从低位到高位看一个数N最多能用几个k伪进制数的位,时间复杂度是 logkN 。然后从高位到低位反着回去看每个位上的值最多是多少,时间复杂度是 logkN ,所以总的时间复杂度是 logkN 。
#python3.5
def getString(chs, n):
if chs == None or len(chs) == 0 or n < 1:
return ""
k = len(chs)
cur = 1
length = 0
while n - cur >= 0:
n -= cur
cur *= k
length += 1
res = [0 for i in range(length)]
for i in range(length):
cur //= k
nCur = n // cur
res[i] = chs[nCur]
n %= cur
return ''.join(res)
从字符串到数字。以chs = [‘A’,’B’,’C’],str = “ABBA”为例,可以知道这个字符串的含义是27有1个,9有2个,3有2个,1有1个,所以对应的数字是52。
def getNum(chs, str1):
def getNthFromChar(chs, ch):
for i in range(len(chs)):
if chs[i] == ch:
return i+1
return -1
if chs == None or len(chs) == 0 or str1 == None or len(str1) == 0:
return 0
res = 0
k = len(chs)
for i in range(len(str1)):
res = res * k + getNthFromChar(chs, str1[i])
return res