python-3.x 如何将字符串表示为数字?

vxqlmq5t  于 2022-12-01  发布在  Python
关注(0)|答案(5)|浏览(187)

我需要用数字来表示一个字符串,但是它有8928313个字符长,注意这个字符串可以包含不止一个字母,而且我还必须能够高效地将它转换回来。我目前的代码(太慢了)看起来像这样:

alpha = 'abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ,.?!@()+-=[]/*1234567890^*{}\'"$\\&#;|%<>:`~_'
alphaLeng = len(alpha)
def letterNumber(letters):
    letters = str(letters)
    cof = 1
    nr = 0
    for i in range(len(letters)):
        nr += cof*alpha.find(letters[i])
        cof *= alphaLeng
        print(i,'        ',len(letters))
    return str(nr)
nwnhqdif

nwnhqdif1#

好吧,既然其他人的回答都很糟糕,我就插一句。
1.你不应该这样做。
1.你不应该这样做。
1.整数和字符数组本质上是一样的:字节。您可以用相同的方式访问这些值。
1.大多数数字表示的上限是8字节(64位)。您看到的是8 MB,或者是最大整数表示的100万倍。您不应该这样做。真的。
1.你不应该这样做。你的数字将只是一个自定义的,巨大的数字类型,将是相同的引擎盖下。
1.如果你真的想这样做,尽管所有的原因以上,这里的如何...

代码

def lshift(a, b):
    # bitwise left shift 8
    return (a << (8 * b))

def string_to_int(data):
    sum_ = 0
    r = range(len(data)-1, -1, -1)
    for a, b in zip(bytearray(data), r):
        sum_ += lshift(a, b)
    return sum_;

不要这样做
说明

字符本质上是字节:它们可以用不同的方式进行编码,但最终可以将它们作为一个字节序列来处理。为了将它们转换为数字,我们可以将它们在序列中的位置左移8位,从而创建一个唯一的数字。r,范围值,是逆序的位置:第4个元素需要左移24字节(3*8)等。
在得到范围并将数据转换为8位整数后,我们可以转换数据并求和,得到我们的唯一标识符。它将与原始数字在字节方面(或按相反的字节顺序)相同,但只是“作为一个数字”。这完全是徒劳的。不要这样做。

性能

任何性能都将被您毫无理由地创建一个相同的对象这一事实所抵消,但这个解决方案的性能相当好。
1,000个元素大约需要486微秒,10,000个元素大约需要20.5毫秒,而100,000个元素大约需要1.5秒。这是可行的,但你不应该这样做。这意味着它的规模为O(n**2),这可能是由于每次整数大小变大时重新分配数据的内存开销。这可能需要~处理所有8 e6个元素需要4个小时(14365秒,将低阶数据拟合为ax**2+bx+c计算得出)。请记住,这一切都是为了获得与原始数据相同的字节表示。

无用

请记住,根据目前的估计,整个宇宙中大约有1 e78到1 e82个原子。这是2^275。你的值将能够表示2^71426504,或者大约是表示宇宙中每个原子所需比特数的260,000倍。你不需要这样的数字,你永远不需要。

col17t5w

col17t5w2#

如果只有ANSII字符,则可以使用ord()chr()
built-in functions

b1zrtrql

b1zrtrql3#

您可以执行几种优化。例如,find方法需要在字符串中搜索相应的字母。使用字典会更快。甚至更快的可能是(基准!)chr函数(如果你对字母顺序不太挑剔的话)和ord函数来反转chr。如果您不需要以任何特定格式显示值,那么最好用NULL填充字符串并将其作为内存中的大二进制数处理。
通过对字符而不是字符索引进行迭代,你可能会得到一些加速。如果你使用Python 2,一个大的range会很慢,因为需要生成一个列表(对于Python 2,使用xrange代替); Python 3使用了一个生成器,所以它更好。
你的print函数会大大降低输出速度,特别是当你输出到一个tty的时候。
一个大的数字库也可以让你加速:Handling big numbers in code

jhiyze9q

jhiyze9q4#

您的alpha.find()函数需要在每个循环中迭代alpha
您可以使用dict来加快速度,因为字典查找是O(1):

alpha = 'abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ,.?!@()+-=[]/*1234567890^*{}\'"$\\&#;|%<>:`~_'

alpha_dict = { letter: index for index, letter in enumerate(alpha)}
print(alpha.find('$'))
# 83
print(alpha_dict['$'])
# 83
krugob8w

krugob8w5#

将字符串存储在不同值的数组中;例如字符串表。在数据集中,使用一个引用号。引用号n对应于字符串表数组的第n个元素。

相关问题