2017-08-18 1 views
0

J'essaie juste d'apprendre la permutation en utilisant le retour arrière. J'ai écrit le code suivant mais il s'arrête après la première sortie.Permutation Python en utilisant le retour arrière

def permutations(str_in, soFar): 

    if len(str_in) != 0: 
     for c in str_in: 
      soFar.append(c) 
      temp_str = str_in 
      temp_str.remove(c) 
      print temp_str, soFar 
      permutations(temp_str, soFar) 
    else: 
     print soFar 

inp = "ABCD"   
str_in = list(inp) 
permutations(str_in, []) 

C'est la sortie que je reçois pour cela:

['B', 'C', 'D'] ['A'] 
['C', 'D'] ['A', 'B'] 
['D'] ['A', 'B', 'C'] 
[] ['A', 'B', 'C', 'D'] 
['A', 'B', 'C', 'D'] 

Je suis sûr que ce soit quelque chose de simple, mais je ne suis pas en mesure de comprendre quelle erreur que je fais ici.

+0

Quelle est votre sortie attendue? – Miket25

+0

Il y a 2 problèmes, avec la même cause racine ici. - 'temp_str' est conçu pour être un _copy_ de la liste d'entrée, mais il prend juste la référence, donc il épuise rapidement les entrées et les récursions -' soFar' devrait être réinitialisé après impression, ou le résultat est incorrect (contient également les résultats précédents). Je ne publie pas de solution car cela génère toujours des doublons. Pas sûr que ce soit l'algorithme approprié, mais c'est mieux. –

+0

J'essaie de générer toutes les permutations possibles telles que [A, B, C, D] puis [A, B, D, C] et ainsi de suite. – akhilc

Répondre

1

Voici la méthode Geeksforgeeks, par Bhavya Jain, de permuter une chaîne. La logique manquante dans votre code est l'étape récursive sur les sous-listes et un comportement d'échange. Voici leur visualisation.

Geeksforgeeks visualization of recursive steps

def permute(a, l, r): 
    if l==r: 
     print toString(a) 
    else: 
     for i in xrange(l,r+1): 
      a[l], a[i] = a[i], a[l] 
      permute(a, l+1, r) 
      a[l], a[i] = a[i], a[l] # backtrack 

# Driver program to test the above function 
string = "ABC" 
n = len(string) 
a = list(string) 
permute(a, 0, n-1) 

sortie

['A', 'B', 'C'] 
['A', 'C', 'B'] 
['B', 'A', 'C'] 
['B', 'C', 'A'] 
['C', 'B', 'A'] 
['C', 'A', 'B'] 
+0

Je suis une série de conférences sur YouTube pour la logique que j'essaie de mettre en œuvre. Dans mon code, l'échange est supposé se produire avec l'implémentation de la boucle for. Supposons que SoFar = ['A', 'B'] 'et' temp_str = ['C', 'D'] '. Ensuite, la boucle devrait se produire sur "C" et "D'". Dans la deuxième itération, il choisira "D'" et l'ajoutera à "SoFar". – akhilc

+0

@akhilc Peut-être devriez-vous voir si vous passez cette liste par référence ou par valeur. Une mutation sur une liste quelque part sur un appel récursif ** ne devrait pas affecter la liste de l'appel précédent, sauf mention explicite. – Miket25

0

je réécrit à nouveau et avec quelques commandes d'impression entre je suis en mesure d'atteindre le résultat souhaité. Mais toujours pas tout à fait sûr de la façon dont ça fonctionne. Je pense que c'est principalement comment python modifie une liste avec chaque appel à la fonction. J'ai dû assigner des listes temporaires deux fois pour m'assurer que les listes d'origine ne sont pas modifiées. Quoi qu'il en soit, le code suivant fonctionne. Deuxième solution en utilisant des chaînes plutôt que des listes, comme mentionné dans mon commentaire ci-dessous.

def permute(String, SoFar): 
    #print "New Func Call: ", "SoFar: ", SoFar,"String: ", String, "\n" 
    if String != "": 
     for c in String: 
      TS = String.replace(c,"") 
      TSF = SoFar+c 
      permute(TS, TSF) 
      #print "A Call Finished", "SoFar: ", SoFar,"String: ", String, "TSF: ", TSF, "TS: ", TS 
    else: 
     print SoFar 

permute("ABC","") 
+0

Juste au cas où quelqu'un trébucherait sur un problème similaire, en ajoutant une autre solution. En lisant un peu plus, j'ai compris que les listes sont modifiables, c'est la raison pour laquelle j'ai dû le réaffecter deux fois pour m'assurer qu'elles ne sont pas modifiées lors de l'appel de la fonction récursive suivante. J'ai donc réécrit à nouveau, mais cette fois les arguments de la fonction sont des chaînes, qui sont immuables. Voila, ça marche sans le réassigner. – akhilc