伪K进制字符串与数字对应

一种字符串和数字的对应关系

伪K进制字符串与数字对应

一个字符类型的数组chs,其中所有的字符都不同,生成相对应的数值关系。

例如,chs=[‘A’,‘B’,‘C’],则字符串与整数的对应关系如下:
A,B,C,AA,AB…CC,AAA…CCC,AAAA…

1,2, 3, 4,  5…12,   13…  39,    40…

例如,chs=[‘A’,‘B’,‘C’,…‘Z’],则字符串与整数的对应关系如下:
A,B…Z, AA,AB…AZ,BA,BB…ZZ, AAA… ZZZ, AAAA…

1,2…26,27, 28…52,53, 54…702,703…18278,18279…

给定一个数组chs,实现根据对应关系完成字符串与整数相互转换的两个函数。


算法思路

多位字符依次对应数字,很自然地想到K进制。
而本题跟K进制略有不同,假定称为伪K进制
对于每个位置上的数,K进制为0 ~ K- 1,而伪K进制为1 ~ K,其中K为字符数组chs字符的个数
保证每个位置上的数至少为1, e.g. chs=[‘A’,‘B’,‘C’], A:1, AA:4(1*3 + 1)。

数字转换为字符串
先求数字对应字符的位数,再求每个位置上的数,即可得到每个位置对应的字符,拼接成字符串。
e.g. 5 - 1 - 3 = 1,两位数, 1在最低位为1,最高位为0,因此最低位为B,最高位为A,转换为字符串为AB。

字符串转换为数字
将每个位置上对应的字符转换成数字,再按K进制求值。
e.g. AB,最高位为A,对应数字为1,最低位为B,对应数字为2,因此对应数值5(1 * 3 + 2)。

时间复杂度为 O ( l o g N × l e n ( c h s ) ) O(logN \times len(chs)) O(logN×len(chs))

相应代码

# 字符串转换为数字
def get_num(chs, s):
    if chs is None or len(chs) == 0 or len(s) == 0:
        return 0
    res = 0
    base = len(chs)
    res += get_char_num(chs, s[0])
    for i in range(1, len(s)):
        res *= base
        res += get_char_num(chs, s[i])
    return res

# 获取字符c对应的数值
def get_char_num(chs, c):
    for i in range(0, len(chs)):
        if c == chs[i]:
            return i + 1

# 数字转换为字符串
def get_str(chs, num):
    if chs is None or len(chs) == 0 or num < 1:
        return ""
    base = len(chs)
    exp_base = 1
    length = 0
    cur = num
    while cur >= exp_base:
        cur -= exp_base
        exp_base *= base
        length += 1
    char_arr = []
    # 从低位到高位加入字符数组
    for i in range(0, length):
        value = cur % base
        cur = cur // base
        char_arr.append(get_num_char(chs, value))
    s = ""
    # 按高位到低位拼接字符串
    for i in range(len(char_arr) - 1, -1, -1):
        s += char_arr[i]
    return s


# 获取数值对应的字符
def get_num_char(chs, num):
    return chs[num]


# 简单测试
if __name__ == '__main__':
    chs = [chr(ord('A') + i)  for i in range(0, 26)]  # 26个大写字母
    s1 = 'A'  # 1
    s2 = 'Z'  # 26
    s3 = 'AA'  # 27
    s4 = 'ZY'  # 701
    print(s1, get_num(chs, s1))
    print(s2, get_num(chs, s2))
    print(s3, get_num(chs, s3))
    print(s4, get_num(chs, s4))

    num1 = 1  # 'A'
    num2 = 26  # 'Z'
    num3 = 27  # 'AA'
    num4 = 701 # 'ZY'
    print(num1, get_str(chs, num1))
    print(num2, get_str(chs, num2))
    print(num3, get_str(chs, num3))
    print(num4, get_str(chs, num4))

有任何疑问和建议,欢迎在评论区留言和指正!

感谢您所花费的时间与精力!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值