2017-02-22 1 views
1

J'ai utilisé le type long pour stocker des nombres et trier en utilisant la méthode de tri normale, mais ce n'était pas assez efficace. Je pense que long(raw_input()) prend trop de temps. Quelqu'un peut-il penser à une manière efficace de le résoudre?Tri des nombres de 10 ** 6 chiffres dans Python 2 efficacement

n = int(raw_input().strip()) 
unsorted = [] 
for i in xrange(n): 
    term = long(raw_input()) 
    unsorted.append(term) 

for i in sorted(unsorted): 
    print i 
+0

chiffres Combien de millions de chiffres avez-vous? –

+0

2 * (10 ** 5) est le nombre de chiffres que j'ai besoin de trier. –

+0

Eh bien, cela devrait être terminé en un clin d'œil, si vous avez assez de mémoire. Je devrais/deviner/la plupart du temps que vous rencontrez est passé dans le fichier i/o. S'il vous plaît faire un code postal (et un lien vers votre fichier de données, le cas échéant) que les lecteurs peuvent simplement copier et coller pour reproduire le problème. –

Répondre

1

Puisque vous avez dit qu'il est une question de programmation compétitive cette solution fonctionnerait autrement il ne fonctionnera jamais car il a besoin beaucoup trop de mémoire et briserait dans les mauvais cas. Mais dans la programmation compétitive, les contraintes ne sont pas tellement et cela devrait fonctionner.

Nous ajoutons simplement le comparateur ie gt et lt méthodes qui décident de la comparaison entre les 2 objets.

class VeryBigNumber(object): 
    def __init__(self,number_string): 
     self.number = number_string 


def __gt__(self,other): 
    if len(self.number)>len(other.number): 
     return True 
    elif len(self.number)<len(other.number): 
     return False 

    for i in xrange(min(len(self.number),len(other.number))): 
     if int(self.number[i])>int(other.number[i]): 
      return True 
     elif int(self.number[i])<int(other.number[i]): 
      return False 
    return False 

def __eq__(self,other): 
    return self.number == other.number 

def __lt__(self,other): 
    return not (self.__eq__(other) or self.__gt__(other)) 

arr = [] 
for i in xrange(n): 
    arr.append(VeryBigNumber(raw_input().strip()) 

arr = sorted(arr) 
for a in arr: 
    print a.number, 

Big Explication:

  1. Dans les commentaires que vous avez dit qu'il est pour une compétition de codage. Cela nous assure que la mémoire est suffisamment petite pour que nous puissions lire en moins d'une seconde.

  2. Nous ne convertissons pas une chaîne trop grande en nombre car cela serait inutile. Au lieu de cela, nous gardons la chaîne telle quelle.

  3. Comment le trions-nous alors? Nous faisons notre propre classe et utilisons des comparaisons de chaînes.

  4. Ils fonctionnent en comparant les chiffres de caractères entre les chaînes et ainsi, un seul caractère est converti en int à un moment très efficace.

  5. J'ai testé le code ci-dessus et il fonctionne correctement

+0

Il existe une différence entre le tri des chaînes et le tri des numéros. Disons que suis le tri 31415, 1, 3, 10 Dans la chaîne, il sera trié comme: 1,10,3,31415 (selon l'ASCII) alors que, Il devrait être 1,3,10,31415 –

+0

@AbhishekKhandelwal : Si tous vos numéros ont le même nombre de chiffres, c'est pareil. – Ryan

+0

@AbhishekKhandelwal Oui! Et c'est pourquoi j'ai ajouté mes propres comparateurs! .. Je n'utilise pas les comparaisons de chaînes standard. Mais cela suppose également qu'il n'y a pas de zéros inutiles au départ –