2009-10-01 8 views

Répondre

3

Ce serait une façon concise:

import re 

s = "aa67bc54c9" 
print ''.join(t * int(n) for t, n in re.findall(r"([a-z]+)([0-9]+)", s)) 

Cette solution utilise une expression régulière pour correspondre à « une ou plusieurs lettres suivies d'un ou plusieurs numéros », la recherche de tous dans la chaîne d'entrée. Ensuite, il utilise une compréhension de liste pour parcourir chaque groupe trouvé, en affectant les lettres à t et les chiffres à n à tour de rôle. La liste génère des chaînes à l'aide de l'opérateur de chaîne *, qui répète une chaîne un certain nombre de fois (int() est utilisé pour convertir la chaîne de chiffres en entier). Enfin, ''.join() est utilisé pour coller tout ensemble.

Pour l'expression régulière, [a-z] est une classe de caractères composée d'une seule lettre (minuscule) de l'alphabet. [a-z]+ signifie une ou plusieurs lettres minuscules. De même, [0-9]+ signifie un ou plusieurs chiffres. Les parenthèses de regroupement autour de chaque composant "capturent" les caractères qu'elles contiennent et les rendent disponibles grâce à la fonction findall(). Il y a deux groupes de parenthèses, donc il y a deux valeurs de sortie, qui sont assignées à t et n dans la liste de compréhension.

+0

Merci beaucoup pour la réponse s'il vous plait exaplin the regex ([a-z] +) ([0-9] +) – Edwards

+0

Totalement aurait battu vous si StackOverflow n'était pas descendu pour moi. Mais je lui aurais donné un peu plus d'espace. –

+0

Pour comprendre la regex, lisez d'abord ma réponse. Pour une explication complète des expressions régulières en Python, voici un excellent tutoriel: http://www.amk.ca/python/howto/regex/ – steveha

3

Voici ma solution Python.

import re 
pat = re.compile("^(\D+)(\d+)(.*)$") 

def rle_expand(s): 
    lst = [] 
    while True: 
     m = pat.match(s) 
     if m: 
      n = int(m.group(2)) 
      lst.append(m.group(1) * n) 
     else: 
      lst.append(s) 
      break 
     s = m.group(3) 
    return "".join(lst) 

s = "aa03bc05d9whew" 

print rle_expand(s) 
# prints aaaaaabcbcbcbcbcdddddddddwhew 

s = “aa67bc54c9” 
print rle_expand(s) 
# prints: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcccccccccc 

Le problème consiste essentiellement à développer un codage en longueur de série. D'abord vous avez une sorte de motif, puis des chiffres qui spécifient combien de fois répéter le motif.

Nous importons d'abord le module re, pour accéder aux expressions régulières de Python.

Ensuite nous compilons un motif une fois, donc nous pouvons l'utiliser plus tard. Que va faire ce motif?

Le motif utilise des parenthèses pour marquer les groupes de lettres de la chaîne correspondant. Il y a trois paires de parens donc cela correspondra à trois groupes. Avant le premier groupe est un caractère '^', qui ancre au début de la chaîne, et après le dernier groupe est un caractère '$', qui ancre à la fin de la chaîne; ceux-ci ne sont pas strictement nécessaires dans ce cas. Le premier groupe correspond à tout ce qui est et non un chiffre utilisant la séquence spéciale \D; le + l'étend pour correspondre à une exécution d'une ou plusieurs instances de non-chiffre. Le deuxième groupe est similaire, en utilisant \d+ pour correspondre à une série d'un ou plusieurs chiffres. Le troisième groupe utilise . pour faire correspondre n'importe quel caractère, puis l'étend avec * pour correspondre à une série de 0 ou plus de n'importe quel caractère. (Notez que * et + sont très similaires, il est juste que * matchs 0 ou plus de quelque chose et + correspond à un ou plusieurs.)

En utilisant un langage standard de Python, nous construisons une chaîne à l'aide d'une liste. Nous commençons avec une liste vide (appelée lst). Tant que le modèle conserve des éléments correspondants, nous ajoutons des éléments à cette liste. Lorsque nous avons terminé, nous utilisons "".join() pour joindre la liste ensemble dans une chaîne.

pat.match() renvoie un objet appelé "objet de correspondance" ou None si la correspondance a échoué.Si la correspondance réussit, nous convertissons le groupe de correspondance 2 en nombre entier et utilisons l'opérateur de répétition de chaîne Python ("multiplier") sur le groupe de correspondance 1 pour effectuer l'expansion de la longueur d'exécution. Après cela, nous rebaptiser le nom s avec les résultats du groupe de correspondance 3, coupant ainsi la partie de la chaîne que nous venons de traiter, et boucle. Si la correspondance échoue, nous ajoutons simplement s à la liste et sortons de la boucle.

Construire une liste puis utiliser "".join() dans la liste est un idiome Python standard. Cela donnera de bonnes performances avec n'importe quelle version de Python. Parce que les chaînes Python sont immuables, vous pouvez souffrir de performances très lentes si vous créez une longue chaîne dynamique en ajoutant plusieurs fois à une chaîne; vous finissez par copier les premières parties de la chaîne plusieurs fois pendant que vous construisez votre chaîne finale. Les listes Python peuvent être ajoutées de manière triviale, puis l'opération de jointure finale est assez rapide. (Les versions récentes de Python ont optimisé le cas où vous ajoutez plusieurs fois une chaîne et ne subissez plus les copies répétées dans ce cas.)

La solution de Greg Hewgill reconnaît uniquement les minuscules de 'a' à 'z pour le texte d'expansion; vous pouvez corriger cela en mettant \D au lieu de [a-z]. Sa solution utilise des plages explicites telles que [0-9] où ma solution utilise les abréviations abrégées Python telles que \d. Sa solution ne fait qu'étendre les séquences codées de la longueur d'exécution; s'il y a une suite qui n'a pas de nombre entier, le mien passe cette séquence inchangée, tandis que la sienne l'ignore silencieusement. Cependant, il faut dire que sa solution est brutalement élégante et j'aurais aimé y penser. :-)

+0

Stevha remercie beaucoup pour votre explication élégante et aussi l'extension regex.Je souhaite stackoverflow permet moi de choisir plus alors sur la réponse honnêtement cette solution d'utiliser une liste pour obtenir ce que je veux était le premier à venir à mon esprit. – Edwards