如何分割大数字?

时间:2010-03-07 00:54:41

标签: python string numbers

我有一个很大的数字,我需要在Python中拆分成较小的数字。我编写了以下代码来交换两者:


def split_number (num, part_size):
    string = str(num)
    string_size = len(string)

    arr = []
    pointer = 0 
    while pointer < string_size:
        e = pointer + part_size
        arr.append(int(string[pointer:e]))
        pointer += part_size
    return arr 

def join_number(arr):
    num = ""
    for x in arr:
        num += str(x)
    return int(num)

但这个数字有所不同。很难调试,因为数字是如此之大,所以在我进入之前,我想我会在这里发布它,看看是否有更好的方法来做或者我是否遗漏了一些明显的东西。

非常感谢。

4 个答案:

答案 0 :(得分:2)

显然,此操作无法保留“部件”中的任何前导0join_number无法接收part_size参数,以便它可以使用所有前导零重建字符串格式吗?

没有发送者和接收者都知道的part_size之类的信息,或者等效的信息(例如用于基于算术的类似分割和连接的基数,大致相当于{{1}根据你使用10**part_size的方式,任务变得相当困难。如果接收者最初对此无能为力,为什么不将part_size(或base等)作为发送和接收的part_size列表中的第一个int放置?这样,编码通常变得“自给自足”,即不需要发送方和接收方都知道的任何补充参数。

答案 1 :(得分:2)

无需转换为字符串和字符串,这对于非常大的数字来说非常耗时

>>> def split_number(n, part_size):
...     base = 10**part_size
...     L = []
...     while n:
...         n,part = divmod(n,base)
...         L.append(part)
...     return L[::-1]
... 
>>> def join_number(L, part_size):
...     base = 10**part_size
...     n = 0
...     L = L[::-1]
...     while L:
...         n = n*base+L.pop()
...     return n
... 
>>> print split_number(1000005,3)
[1, 0, 5]
>>> print join_number([1,0,5],3)
1000005
>>> 

在这里你可以看到只需将数字转换为str所需的时间比我的整个功能要长!

>>> from time import time
>>> t=time();b = split_number(2**100000,3000);print time()-t
0.204252004623
>>> t=time();b = split_number(2**100000,30);print time()-t
0.486856222153    
>>> t=time();b = str(2**100000);print time()-t
0.730905056

答案 2 :(得分:1)

您应该考虑将以下数字拆分为3个大小的块:

1000005 -> 100 000 5

你有两个问题。首先,如果你把那些整数放回去,你会得到:

100 0 5 -> 100005

(即,中间的一个是0,而不是000),这不是你开始的。第二个问题是你不确定最后一部分应该是多大。

我会确保您首先使用长度与零件尺寸完全相同的字符串,因此您知道完全每个零件应该有多大:

def split_number (num, part_size):
    string = str(num)
    string_size = len(string)
    while string_size % part_size != 0:
        string = "0%s"%(string)
        string_size = string_size + 1

    arr = []
    pointer = 0
    while pointer < string_size:
        e = pointer + part_size
        arr.append(int(string[pointer:e]))
        pointer += part_size
    return arr

其次,确保将每个部件的部件放回到正确的长度(确保您不会在前一部分放置前导零):

def join_number(arr, part_size):
    fmt_str = "%%s%%0%dd"%(part_size)
    num = arr[0]
    for x in arr[1:]:
        num = fmt_str%(num,int(x))
    return int(num)

将所有这些结合起来,以下完整的程序:

#!/usr/bin/python

def split_number (num, part_size):
    string = str(num)
    string_size = len(string)
    while string_size % part_size != 0:
        string = "0%s"%(string)
        string_size = string_size + 1

    arr = []
    pointer = 0
    while pointer < string_size:
        e = pointer + part_size
        arr.append(int(string[pointer:e]))
        pointer += part_size
    return arr

def join_number(arr, part_size):
    fmt_str = "%%s%%0%dd"%(part_size)
    num = arr[0]
    for x in arr[1:]:
        num = fmt_str%(num,int(x))
    return int(num)

x = 1000005
print x
y = split_number(x,3)
print y
z = join_number(y,3)
print z

产生输出:

1000005
[1, 0, 5]
1000005

表明它会一起回归。

请记住,我几年没有做过Python。几乎可以肯定有一种更“Pythonic”的方法来处理那些新奇的lambdas和事物(或者Python称之为),但是,由于你的代码是基本形式,我只回答了使其工作所需的最小变化。哦是的,并且要警惕负数: - )

答案 3 :(得分:0)

这是Alex Martelli回答的一些代码。

def digits(n, base):
    while n:
        yield n % base
        n //= base

def split_number(n, part_size):
    base = 10 ** part_size
    return list(digits(n, base))

def join_number(digits, part_size):
    base = 10 ** part_size
    return sum(d * (base ** i) for i, d in enumerate(digits))