我需要用数字来表示一个字符串,但是它有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)
5条答案
按热度按时间nwnhqdif1#
好吧,既然其他人的回答都很糟糕,我就插一句。
1.你不应该这样做。
1.你不应该这样做。
1.整数和字符数组本质上是一样的:字节。您可以用相同的方式访问这些值。
1.大多数数字表示的上限是8字节(64位)。您看到的是8 MB,或者是最大整数表示的100万倍。您不应该这样做。真的。
1.你不应该这样做。你的数字将只是一个自定义的,巨大的数字类型,将是相同的引擎盖下。
1.如果你真的想这样做,尽管所有的原因以上,这里的如何...
代码
不要这样做
说明
字符本质上是字节:它们可以用不同的方式进行编码,但最终可以将它们作为一个字节序列来处理。为了将它们转换为数字,我们可以将它们在序列中的位置左移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倍。你不需要这样的数字,你永远不需要。
col17t5w2#
如果只有ANSII字符,则可以使用
ord()
和chr()
。built-in functions
b1zrtrql3#
您可以执行几种优化。例如,
find
方法需要在字符串中搜索相应的字母。使用字典会更快。甚至更快的可能是(基准!)chr
函数(如果你对字母顺序不太挑剔的话)和ord
函数来反转chr
。如果您不需要以任何特定格式显示值,那么最好用NULL填充字符串并将其作为内存中的大二进制数处理。通过对字符而不是字符索引进行迭代,你可能会得到一些加速。如果你使用Python 2,一个大的
range
会很慢,因为需要生成一个列表(对于Python 2,使用xrange
代替); Python 3使用了一个生成器,所以它更好。你的
print
函数会大大降低输出速度,特别是当你输出到一个tty的时候。一个大的数字库也可以让你加速:Handling big numbers in code
jhiyze9q4#
您的
alpha.find()
函数需要在每个循环中迭代alpha
。您可以使用
dict
来加快速度,因为字典查找是O(1):krugob8w5#
将字符串存储在不同值的数组中;例如字符串表。在数据集中,使用一个引用号。引用号n对应于字符串表数组的第n个元素。