4
votes

Récursivité de chaîne Python, index de chaîne hors limites

Je suis nouveau en python et très mauvais pour penser de manière récursive. Ce code me donne un IndexError: string index out of range . Et je ne sais pas comment le corriger.

Traceback (most recent call last):
  File "soRecursivePermutations.py", line 25, in <module>
    get_permutations('abc')
  File "soRecursivePermutations.py", line 23, in get_permutations
    return permutation(sequence)
  File "soRecursivePermutations.py", line 20, in permutation
    permutationhelp(sequence,"")
  File "soRecursivePermutations.py", line 12, in permutationhelp
    c= sequence[i]
IndexError: string index out of range

Exemple:

get_permutations('abc')
['abc', 'acb', 'bac', 'bca', 'cab', 'cba']

Le suivi est le suivant:

def get_permutations(sequence):

    def permutationhelp(sequence,chosen):

        if sequence=="":
            print(chosen)

        else:

            for i in range(len(sequence)):
                c= sequence[i]
                chosen +=c
                sequence=sequence[i+1:]
                permutationhelp(sequence,chosen)
                sequence=c+sequence
                chosen=chosen[:-1]

    def permutation(sequence):
        permutationhelp(sequence,"")


    return permutation(sequence)


2 commentaires

Veuillez mettre à jour votre question avec la façon dont vous appelez la fonction, les données d'entrée et les données de sortie attendues, ainsi que le texte intégral de la trace d'erreur que vous voyez.


Une autre chose qui nous serait utile, est de savoir si vous pouviez fournir ce que vous prévoyez de se produire? C'est à dire. Quel devrait être le résultat lorsque vous appelez get_permutations () .


5 Réponses :


2
votes

Devrait fortement envisager d'utiliser:

perm = [''.join(p) for p in itertools.permutations('abc')]

Ou si vous souhaitez stocker dans list:

import itertools

for p in itertools.permutations("abc"):
    print(''.join(p))
# abc
# acb
# bac
# bca
# cab
# cba

p>


3 commentaires

Je crois qu'OP essaie d'apprendre la manière récursive de faire cela. Avez-vous une réponse à cela?


merci, mais je suis nouveau. Et j'essaie de comprendre comment fonctionne la récursivité et comment je peux penser récursive. Je ne veux pas importer itertools


C'est correct, mais l'OP semble vouloir une solution récursive



2
votes

La raison de votre traçage est ici:

['abc', 'acb', 'bac', 'bca', 'cab', 'cba']

La première ligne laisse la séquence avec juste la fin de la chaîne. et la troisième ligne n'ajoute qu'un seul caractère à la séquence , donc la séquence devient plus courte à mesure que vous parcourez la boucle.

Cependant, ceci est probablement le programme que vous recherchiez:

# https://stackoverflow.com/a/53088155/4834
def remove_at(i, s):
    return s[:i] + s[i + 1:]

def permutationhelp(sequence, chosen, collect):
    if sequence == "":
        collect.append(chosen)
    else:
        for i,c in enumerate(sequence):
            permutationhelp(remove_at(i, sequence), chosen + c, collect)

def get_permutations(sequence):
    collect = []
    permutationhelp(sequence, "", collect)
    return collect

print(get_permutations('abc'))

Sortie:

sequence=sequence[i+1:]
permutationhelp(sequence,chosen)
sequence=c+sequence


0 commentaires

0
votes

Je pense que vous voudrez peut-être l'aborder différemment. En suivant votre code, je pense que vous voulez simplement réduire la liste et imprimer le résultat sur la console lorsque vous manquez de séquence, mais je ne vois aucune logique pour la permutation réelle. Pardonne-moi si c'est là et je l'ai manqué.

Voici comment j'y pense. Commencez par le premier élément "a", gardez un index "i" pour le passer dans votre fonction d'assistance puis échangez avec une liste qui n'inclut pas "a" donc dans ce cas ce serait "b et c". Puis concattez cela avec votre caractère d'index "i", et débloquez également la liste un avec ce même caractère à nouveau. Cela afficherait "abc et acb".

Ensuite, j'incrémentais le "i" et j'appelais à nouveau votre assistant. Alors maintenant, votre élément est "b" et la liste de permutation est "a et c" et produit "bac" et "bca". Puis incrémentez et répétez à nouveau, ce qui produit "cab" et "cba". Vous pouvez avoir votre cas de base de récursion comme i étant le même que len (séquence). J'espère que je ne t'ai perdu nulle part. Je ne l'ai pas codé parce que je pensais que vous essayiez d'apprendre en faisant. Bonne chance!


0 commentaires

0
votes

J'ai dû le copier pour découvrir le problème, l'exception indique clairement que vous essayiez d'accéder à un index plus long que le tableau fourni.

J'ai modifié peu de choses dans votre solution.

  • J'ai arrêté la dépendance de la variable "choisie" dans la récursivité

  • Je lui ai fait renvoyer une liste des résultats.

    ['abc', 'acb', 'bac', 'bca', 'cab', 'cba']
    
  • résultat:

    def get_permutations(sequence):
    
     def permutationhelp(sequence):
       if len(sequence) == 1:
        return sequence
    result = []
    for i in range(len(sequence)):
        c = sequence[i]
        remaining = sequence[:i] + sequence[i+1:]
        for perm in permutationhelp(remaining):
            result.append(c + perm)
    
    return result
    
    def permutation(sequence):
      result = permutationhelp(sequence)
      print(result)
    
    
    return permutation(sequence)
    
    get_permutations('abc')
    


    0 commentaires

    1
    votes

    @quamrana a donné la bonne explication. Ici, je pense que les codes suivants sont plus utiles pour OP pour comprendre son erreur et l'algorithme récursif.

    >>> get_permutations('abc')
    abc
    acb
    bac
    bca
    cab
    cba
    

    testcase

    def get_permutations(sequence):
        def permutationhelp(sequence, chosen):
            if sequence == "":
                print(chosen)
            else:
                for i in range(len(sequence)):
                    c = sequence[i]
                    chosen += c
                    sequence = sequence[:i] + sequence[i+1:]
                    permutationhelp(sequence,chosen)
                    sequence = sequence[:i] + c + sequence[i:]
                    chosen = chosen[:-1]
    
        def permutation(sequence):
            permutationhelp(sequence,"")
    
        return permutation(sequence)
    
    


    0 commentaires