有没有更快的方法将数字转换为名称? [英] Is there a faster way of converting a number to a name?

查看:78
本文介绍了有没有更快的方法将数字转换为名称?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下代码定义了映射到数字的一系列名称.它旨在采用数字并检索特定名称.该类通过确保名称存在于其缓存中进行操作,然后通过索引到其缓存中来返回名称.问题是:如何在不存储缓存的情况下根据数字计算名称?

The following code defines a sequence of names that are mapped to numbers. It is designed to take a number and retrieve a specific name. The class operates by ensuring the name exists in its cache, and then returns the name by indexing into its cache. The question in this: how can the name be calculated based on the number without storing a cache?

该名称可以被认为是以63为底的数字,除了第一个数字始终以53为底.

The name can be thought of as a base 63 number, except for the first digit which is always in base 53.

class NumberToName:

    def __generate_name():
        def generate_tail(length):
            if length > 0:
                for char in NumberToName.CHARS:
                    for extension in generate_tail(length - 1):
                        yield char + extension
            else:
                yield ''
        for length in itertools.count():
            for char in NumberToName.FIRST:
                for extension in generate_tail(length):
                    yield char + extension

    FIRST = ''.join(sorted(string.ascii_letters + '_'))
    CHARS = ''.join(sorted(string.digits + FIRST))
    CACHE = []
    NAMES = __generate_name()

    @classmethod
    def convert(cls, number):
        for _ in range(number - len(cls.CACHE) + 1):
            cls.CACHE.append(next(cls.NAMES))
        return cls.CACHE[number]

    def __init__(self, *args, **kwargs):
        raise NotImplementedError()

以下交互式会话显示了一些应按顺序返回的值.

The following interactive sessions show some of the values that are expected to be returned in order.

>>> NumberToName.convert(0)
'A'
>>> NumberToName.convert(26)
'_'
>>> NumberToName.convert(52)
'z'
>>> NumberToName.convert(53)
'A0'
>>> NumberToName.convert(1692)
'_1'
>>> NumberToName.convert(23893)
'FAQ'

不幸的是,这些数字需要映射到这些确切的名称(以允许反向转换).

Unfortunately, these numbers need to be mapped to these exact names (to allow a reverse conversion).

请注意::接收到可变数量的比特并将其明确转换为数字.该数字应明确转换为Python标识符名称空间中的名称.最终,有效的Python名称将被转换为数字,而这些数字将被转换为可变的位数.

Please note: A variable number of bits are received and converted unambiguously into a number. This number should be converted unambiguously to a name in the Python identifier namespace. Eventually, valid Python names will be converted to numbers, and these numbers will be converted to a variable number of bits.

最终解决方案:

import string

HEAD_CHAR = ''.join(sorted(string.ascii_letters + '_'))
TAIL_CHAR = ''.join(sorted(string.digits + HEAD_CHAR))
HEAD_BASE, TAIL_BASE = len(HEAD_CHAR), len(TAIL_CHAR)

def convert_number_to_name(number):
    if number < HEAD_BASE: return HEAD_CHAR[number]
    q, r = divmod(number - HEAD_BASE, TAIL_BASE)
    return convert_number_to_name(q) + TAIL_CHAR[r]

推荐答案

这是一个有趣的小问题,只有1个错误.

This is a fun little problem full of off by 1 errors.

无循环:

import string

first_digits = sorted(string.ascii_letters + '_')
rest_digits = sorted(string.digits + string.ascii_letters + '_')

def convert(number):
    if number < len(first_digits):
        return first_digits[number]

    current_base = len(rest_digits)
    remain = number - len(first_digits)
    return convert(remain / current_base) + rest_digits[remain % current_base]

测试:

print convert(0)
print convert(26)
print convert(52)
print convert(53)
print convert(1692)
print convert(23893)

输出:

A
_
z
A0
_1
FAQ

这篇关于有没有更快的方法将数字转换为名称?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆