2010-03-07 53 views
0

我有一個很大的數字,我需要在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) 

但是數字會有所不同。這很難調試,因爲數量太大了,所以在我進入之前,我想我會在這裏發佈它,看看是否有更好的方法來做到這一點,或者我是否錯過了明顯的東西。

非常感謝。

+3

每個塊中的前導零? – 2010-03-07 01:00:01

回答

2

很明顯,任何領先的0 s在「部分」不能通過此操作保留。不能join_number也收到part_size參數,以便它可以重建與所有前導零的字符串格式?

沒有一些信息,比如part_size是上已知的發送端兩者和接收器,或同等學歷(如基數使用了類似的分裂和加入基於算法,​​大致相當於10**part_size給你的方式使用part_size),任務變得相當困難。如果接收機最初對此無能爲力,爲什麼不把part_size(或基地等)作爲發送和接收的arr列表中的第一個int?這樣,編碼變得「自給自足」,即不需要發送者和接收者都知道的任何補充參數。

+0

啊,當然是領先零。可以使數組中的第一個整數爲part_size。 非常感謝您的幫助,我不相信我錯過了這一點。 – Reality 2010-03-07 01:09:02

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。幾乎可以肯定的是,使用這些新開發的lambda表達式和其他東西(或者任何Python稱爲它們)的方法會有更多的「Pythonic」方法,但是,由於代碼是基本形式,因此我只是回答了需要進行的最小更改才能使其運行。噢,並警惕負數:-)

+0

num =''%s%* d'%(num,part_size,int(x))' – 2010-03-07 14:23:13

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 
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))