2010-03-07 11 views
0

J'ai un grand nombre, que j'ai besoin de diviser en plus petits nombres en Python. J'ai écrit le code suivant pour échanger entre les deux:Comment diviser les grands nombres?


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) 

Mais le nombre revient différemment. Il est difficile de déboguer parce que le nombre est si grand, donc avant que j'y entre, j'ai pensé que je l'afficherais ici pour voir s'il y a une meilleure façon de le faire ou si quelque chose me manque.

Merci beaucoup.

+3

des zéros dans chaque tronçon? –

Répondre

2

De toute évidence, les 0 s principaux dans les «parties» ne peuvent pas être conservés par cette opération. join_number ne peut pas également recevoir l'argument part_size, afin qu'il puisse reconstruire les formats de chaîne avec tous les zéros de tête?

Sans certaines informations telles que part_size qui est connu à la fois l'émetteur et le récepteur, ou l'équivalent (tels que le nombre de base à utiliser pour une fraction similaire et jointure basée sur l'arithmétique, à peu près équivalent à 10**part_size donné la façon dont vous êtes en utilisant part_size), la tâche devient un peu plus difficile. Si le récepteur est totalement désemparé à ce sujet, pourquoi ne pas simplement placer le part_size (ou base, etc) comme tout premier int dans la liste arr qui est envoyé et reçu? De cette manière, le codage devient trivialement "auto-suffisant", c'est-à-dire qu'il n'a besoin d'aucun paramètre supplémentaire connu à la fois de l'émetteur et du récepteur.

+0

Ahh, les zéros en tête, bien sûr. Il est possible de créer le premier nombre entier dans le tableau, part_size. Merci beaucoup pour votre aide, je ne crois pas avoir manqué ça. – Reality

1

Vous devriez penser au numéro suivant divisé en morceaux de 3 dimensions:

1000005 -> 100 000 5 

Vous avez deux problèmes. La première est que si vous mettez ces entiers retour ensemble, vous obtenez:

100 0 5 -> 100005 

(à savoir, le milieu est un 0, et non 000) qui est pas ce que vous avez commencé. Le deuxième problème est que vous n'êtes pas sûr de la taille de la dernière partie.

Je veillerai à ce que vous êtes le premier à l'aide d'une chaîne dont la longueur est un multiple exact de la taille de la pièce de sorte que vous savez exactement la taille de chaque pièce doit être:

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 

Deuxièmement, assurez-vous que vous mettez les pièces en arrière en même temps que la bonne longueur pour chaque partie (vous assurant de ne pas mettre des zéros à gauche sur la première partie du cours):

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) 

mettre tout ensemble, le programme complet ci-dessous:

#!/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 

produit la sortie:

1000005 
[1, 0, 5] 
1000005 

qui montre qu'il va ensemble.

N'oubliez pas que je n'ai pas fait de Python depuis quelques années. Il y a presque certainement un moyen plus "Pythonic" de le faire avec ces lambdas et objets nouveaux (ou tout ce que Python les appelle) mais, comme votre code était de base, j'ai juste répondu avec les changements minimes requis pour le faire fonctionner .Ah oui, et méfiez-vous des nombres négatifs :-)

+0

num = ''% s% * d'% (num, taille_part, int (x))' –

2

Il n'y a pas besoin de convertir en chaînes, ce qui peut prendre beaucoup de temps pour les nombres vraiment grands

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

Ici vous pouvez voir que tout convertir le nombre à un str prend plus de temps que l'ensemble de ma fonction!

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

Voici un code pour la réponse d'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)) 
Questions connexes