2017-10-20 24 views
0

Je suis un tuteur d'un ami en python, pas très bon moi-même. La tâche consiste à écrire un script qui inverse un langage alien inventé dans lequel ils répètent chaque séquence de voyelle après avoir ajouté la lettre "p". Quelques exemples:Optimisation du script python débutant sur le remplacement de la sous-chaîne

tomato -> topomapatopogroovy->groopoovy et beautiful -> beaupeautipifupul

L'objectif est d'inverser cette tendance. De groopoovy -> groovy.

Comme il s'agit d'une affectation hollandaise, il existe une exception: "ij" est vu comme une voyelle. Donc blijpij -> blij (ce qui complique beaucoup les choses, je trouve)

Ma solution me semble assez volumineuse et je m'intéresse à une solution meilleure, plus élégante. Comme il s'agit d'un cours d'introduction à la programmation, les bases sont la clé, malheureusement.

word = input() 
    vowels = ('a', 'e', 'i', 'o', 'u') 
    position = 0 
    solution = "" 
    while position < len(word): 
     if word[position] == 'p':  # obviously, search for the letter 'p' 
      add = 1      # keep track of the sub string size 
      group = "" 
      while True:     # loop to get consecutive vowels 
       if word[position + add] in vowels: 
        group += word[position + add] 
        if word[position + add] == 'i' and word[position + add + 1] == 'j': # recognize the "ij" 
         group += 'j' 
         add += 1 
        add += 1 
       else: 
        break 
       if position+add == len(word):  # stay within the bounds of the string 
        break 
      add -= 1 
      if word[position - add:position].lower() == group.lower() and group != "": 
       position += add 
      else: 

       solution += 'p' 
     else: 
      solution += word[position] 
     position += 1 
    print(solution) 

Répondre

0

Qu'en est-ce, pour une classe Python d'introduction. Il y a plusieurs exemples de mots en haut; change juste les commentaires #. Au lieu de vérifier "p" à chaque pas, je vérifie le début d'une séquence de voyelle. Cette séquence sera toujours terminée par "p". C'est le seul cas où vous ne voulez pas ajouter le personnage à la solution; Au lieu de cela, vous voulez passer à la fin de la séquence de voyelle.

Le fait que "ij" soit une voyelle ne crée pas de cas particulier, car "i" commence une séquence de voyelle.

word = "poopoo-poopoo" 
# word = "poopooh" 
# word = "hijipijinks" 
# word = "apapepe" 
# word = "copovfepefepe" 
vowels = ('a', 'e', 'i', 'o', 'u') 
position = 0 
solution = "" 
vowel_count = 0 # consecutive vowels 
while position < len(word): 
    c = word[position] 
    if vowel_count > 0: 
     if c == 'p': 
      position += vowel_count + 1 
      vowel_count = 0 
      continue 
     vowel_count += 1 
    else: 
     if c in vowels: 
      vowel_count = 1 
    solution += c 
    position += len(c) 

print(solution) 
+0

C'est en effet la solution la plus élégante que je cherchais. Merci Paul. Il a fallu un petit ajustement pour vérifier les parties gauche et droite quand 'c == 'p'', sinon les mots comme' cape 'sont éclatés. –

+0

Le programme suppose que le mot d'entrée est formaté en fonction de votre recette et ne le vérifie pas pour des erreurs de syntaxe ou d'orthographe. Votre version ne le vérifie pas non plus. "cape" n'est pas une entrée valide. "capapepe" * est * valide et donne correctement le résultat "cape". –

1
import re 
input_text = "tomato" 
encoded = re.sub('([aeiou]+)','\\1p\\1',input_text) 
print(encoded) 
decoded = re.sub('([aeiou]+)p\\1','\\1',encoded) 
print(decoded) 

devrait faire juste que

+0

Merci pour la réponse rapide. Je pensais aussi à regex, mais je ne savais pas comment gérer la partie "ij" -is-a-voyelle. Ne peut toujours pas penser à un moyen pour regex de faire cela .. –

+1

@FrankVermeulen Changer '[aeiou]' en '(?: [Aeiou] | ij)' – Barmar

+0

Utilisez une chaîne brute de sorte que vous n'avez pas besoin de doubler le antislashs. – Barmar