Anda harus menggabungkan huruf yang diubah sebagai string.
['stack', 'stakc', 'stcak', 'stcka', 'stkac', 'stkca', 'satck', 'satkc', 'sactk', 'sackt', 'saktc', 'sakct', ' sctak ',' sctka ',' scatk ',' scakt ',' sckta ',' sckat ',' sktac ',' sktca ',' skatc ',' skact ',' skcta ',' skcat ',' tsack ' , 'tsakc', 'tscak', 'tscka', 'tskac', 'tskca', 'tasck', 'taskc', 'tacsk', 'tacks', 'taksc', 'takcs', 'tcsak', ' tcska ',' tcask ',' tcaks ',' tcksa ',' tckas ',' tksac ',' tksca ',' tkasc ',' tkacs ',' tkcsa ',' tkcas ',' astck ','astkc ',' asctk ',' asckt ',' asktc ',' askct ',' atsck ',' atskc ',' atcsk ',' atcks ',' atksc ',' atkcs ',' acstk ',' acskt ' , 'actk', 'actks', 'ackst', 'ackts', 'akstc', 'aksct', 'aktsc', 'aktcs', 'akcst', 'akcts', 'cstak', 'cstka', ' csatk ',' csakt ',' cskta ',' cskat ',' ctsak ',' ctska ',' ctask ',' ctaks ',' ctksa ',' ctkas ',' castk ',' caskt ',' catsk ' , 'catks', 'cakst', 'cakts', 'cksta', 'cksat', 'cktsa', 'cktas', 'ckast', 'ckats', 'kstac', 'kstca', 'ksatc','ksact', 'kscta', 'kscat', 'ktsac', 'ktsca', 'ktasc', 'ktacs', 'ktcsa', 'ktcas', 'kastc', 'kasct', 'katsc', 'katcs ',' kacst ',' kacts ',' kcsta ',' kcsat ',' kctsa ',' kctas ',' kcast ',' kcats ']
Jika Anda bermasalah dengan duplikat, coba paskan data Anda ke dalam struktur tanpa duplikat seperti set
:
Terima kasih kepada @pst karena telah menunjukkan bahwa ini bukanlah apa yang secara tradisional kami anggap sebagai pemeran tipe, tetapi lebih merupakan panggilan ke set()
konstruktor.
set(...)
tidak "dilemparkan". Sebaliknya, ia menghasilkan (dan menghasilkan) set yang mewakili koleksi masukan: setelah dibuat ia tidak memiliki kaitan dengan koleksi masukan (dan merupakan objek yang berbeda, bukan hanya tampilan yang berbeda).bool
,, adalah fungsi yang mengevaluasi ke bool (True / False) tergantung pada input. Saya menemukan penggunaan "cast" di sini palsu dan menyesatkan ...Anda bisa mendapatkan semua N! permutasi tanpa banyak kode
def permutations(string, step = 0): # if we've gotten to the end, print the permutation if step == len(string): print "".join(string) # everything to the right of step has not been swapped yet for i in range(step, len(string)): # copy the string (store as array) string_copy = [character for character in string] # swap the current index with the step string_copy[step], string_copy[i] = string_copy[i], string_copy[step] # recurse on the portion of the string that has not been swapped yet (now it's index will begin with step + 1) permutations(string_copy, step + 1)
sumber
step == len(string)
bukanstep == len(string) - 1
?Berikut adalah cara lain untuk melakukan permutasi string dengan kode minimal. Kami pada dasarnya membuat loop dan kemudian kami terus menukar dua karakter sekaligus, Di dalam loop kami akan melakukan rekursi. Perhatikan, kami hanya mencetak ketika pengindeks mencapai panjang string kami. Contoh: ABC i untuk titik awal kita dan parameter rekursi kita j untuk loop kita
berikut adalah bantuan visual cara kerjanya dari kiri ke kanan atas ke bawah (adalah urutan permutasi)
Kode :
def permute(data, i, length): if i==length: print(''.join(data) ) else: for j in range(i,length): #swap data[i], data[j] = data[j], data[i] permute(data, i+1, length) data[i], data[j] = data[j], data[i] string = "ABC" n = len(string) data = list(string) permute(data, 0, n)
sumber
Pengguna Stack Overflow telah memposting beberapa solusi kuat tetapi saya ingin menunjukkan solusi lain. Yang ini menurut saya lebih intuitif
Idenya adalah untuk string yang diberikan: kita dapat menggunakan algoritma (pseudo-code):
Saya harap ini membantu seseorang!
def permutations(string): """ Create all permutations of a string with non-repeating characters """ permutation_list = [] if len(string) == 1: return [string] else: for char in string: [permutation_list.append(char + a) for a in permutations(string.replace(char, "", 1))] return permutation_list
sumber
Berikut fungsi sederhana untuk mengembalikan permutasi unik:
def permutations(string): if len(string) == 1: return string recursive_perms = [] for c in string: for perm in permutations(string.replace(c,'',1)): revursive_perms.append(c+perm) return set(revursive_perms)
sumber
revursive_perms
->recursive_perms
. 2. Ini akan menghemat RAM dan waktu jikarecursive_perms
adalah satu set daripada daftar yang Anda ubah ke satu set dalam pernyataan return. 3. Akan lebih efisien untuk menggunakan pemotongan string daripada.replace
membangun arg ke panggilan rekursifpermutations
. 4. Ini bukan ide yang baik untuk digunakanstring
sebagai nama variabel karena bayangan namastring
modul standar .Berikut pendekatan lain yang berbeda dari apa yang diposting @Adriano dan @illerucis. Ini memiliki runtime yang lebih baik, Anda dapat memeriksanya sendiri dengan mengukur waktu:
def removeCharFromStr(str, index): endIndex = index if index == len(str) else index + 1 return str[:index] + str[endIndex:] # 'ab' -> a + 'b', b + 'a' # 'abc' -> a + bc, b + ac, c + ab # a + cb, b + ca, c + ba def perm(str): if len(str) <= 1: return {str} permSet = set() for i, c in enumerate(str): newStr = removeCharFromStr(str, i) retSet = perm(newStr) for elem in retSet: permSet.add(c + elem) return permSet
Untuk sembarang string "dadffddxcf" butuh 1,1336 detik untuk perpustakaan permutasi, 9,125 detik untuk implementasi ini dan 16,357 detik untuk versi @ Adriano dan @illerucis. Tentu Anda tetap bisa mengoptimalkannya.
sumber
itertools.permutations
bagus, tetapi tidak cocok dengan urutan yang mengandung elemen berulang. Itu karena secara internal itu mengizinkan indeks urutan dan tidak menyadari nilai item urutan.Tentu, itu mungkin untuk memfilter keluaran
itertools.permutations
melalui satu set untuk menghilangkan duplikat, tetapi masih membuang waktu menghasilkan duplikat tersebut, dan jika ada beberapa elemen berulang dalam urutan dasar akan ada banyak duplikat. Selain itu, menggunakan collection untuk menahan hasil akan membuang-buang RAM, meniadakan manfaat penggunaan iterator di tempat pertama.Untungnya, ada pendekatan yang lebih efisien. Kode di bawah ini menggunakan algoritme ahli matematika India abad ke-14, Narayana Pandita, yang dapat ditemukan di artikel Wikipedia tentang Permutasi . Algoritme kuno ini masih merupakan salah satu cara tercepat yang diketahui untuk menghasilkan permutasi secara berurutan, dan ini cukup kuat, karena menangani permutasi yang mengandung elemen berulang dengan benar.
def lexico_permute_string(s): ''' Generate all permutations in lexicographic order of string `s` This algorithm, due to Narayana Pandita, is from https://en.wikipedia.org/wiki/Permutation#Generation_in_lexicographic_order To produce the next permutation in lexicographic order of sequence `a` 1. Find the largest index j such that a[j] < a[j + 1]. If no such index exists, the permutation is the last permutation. 2. Find the largest index k greater than j such that a[j] < a[k]. 3. Swap the value of a[j] with that of a[k]. 4. Reverse the sequence from a[j + 1] up to and including the final element a[n]. ''' a = sorted(s) n = len(a) - 1 while True: yield ''.join(a) #1. Find the largest index j such that a[j] < a[j + 1] for j in range(n-1, -1, -1): if a[j] < a[j + 1]: break else: return #2. Find the largest index k greater than j such that a[j] < a[k] v = a[j] for k in range(n, j, -1): if v < a[k]: break #3. Swap the value of a[j] with that of a[k]. a[j], a[k] = a[k], a[j] #4. Reverse the tail of the sequence a[j+1:] = a[j+1:][::-1] for s in lexico_permute_string('data'): print(s)
keluaran
Tentu saja, jika Anda ingin mengumpulkan string yang dihasilkan ke dalam daftar yang dapat Anda lakukan
list(lexico_permute_string('data'))
atau dalam versi Python terbaru:
[*lexico_permute_string('data')]
sumber
kenapa kamu tidak sederhana melakukan:
from itertools import permutations perms = [''.join(p) for p in permutations(['s','t','a','c','k'])] print perms print len(perms) print len(set(perms))
Anda tidak mendapatkan duplikat seperti yang Anda lihat:
['stack', 'stakc', 'stcak', 'stcka', 'stkac', 'stkca', 'satck', 'satkc', 'sactk', 'sackt', 'saktc', 'sakct', 'sctak', 'sctka', 'scatk', 'scakt', 'sckta', 'sckat', 'sktac', 'sktca', 'skatc', 'skact', 'skcta', 'skcat', 'tsack', 'tsakc', 'tscak', 'tscka', 'tskac', 'tskca', 'tasck', 'taskc', 'tacsk', 'tacks', 'taksc', 'takcs', 'tcsak', 'tcska', 'tcask', 'tcaks', 'tcksa', 'tckas', 'tksac', 'tksca', 'tkasc', 'tkacs', 'tkcsa', 'tkcas', 'astck', 'astkc', 'asctk', 'asckt', 'asktc', 'askct', 'atsck', 'atskc', 'atcsk', 'atcks', 'atksc', 'atkcs', 'acstk', 'acskt', 'actsk', 'actks', 'ackst', 'ackts', 'akstc', 'aksct', 'aktsc', 'aktcs', 'akcst', 'akcts', 'cstak', 'cstka', 'csatk', 'csakt', 'cskta', 'cskat', 'ctsak', 'ctska', 'ctask', 'ctaks', 'ctksa', 'ctkas', 'castk', 'caskt', 'catsk', 'catks', 'cakst', 'cakts', 'cksta', 'cksat', 'cktsa', 'cktas', 'ckast', 'ckats', 'kstac', 'kstca', 'ksatc', 'ksact', 'kscta', 'kscat', 'ktsac', 'ktsca', 'ktasc', 'ktacs', 'ktcsa', 'ktcas', 'kastc', 'kasct', 'katsc', 'katcs', 'kacst', 'kacts', 'kcsta', 'kcsat', 'kctsa', 'kctas', 'kcast', 'kcats'] 120 120 [Finished in 0.3s]
sumber
def permute(seq): if not seq: yield seq else: for i in range(len(seq)): rest = seq[:i]+seq[i+1:] for x in permute(rest): yield seq[i:i+1]+x print(list(permute('stack')))
sumber
Lihat
itertools.combinations
atauitertools.permutations
.sumber
Berikut adalah versi kode illerucis yang sedikit lebih baik untuk mengembalikan daftar semua permutasi string
s
dengan karakter berbeda (tidak harus dalam urutan leksikografik), tanpa menggunakan alat itert:def get_perms(s, i=0): """ Returns a list of all (len(s) - i)! permutations t of s where t[:i] = s[:i]. """ # To avoid memory allocations for intermediate strings, use a list of chars. if isinstance(s, str): s = list(s) # Base Case: 0! = 1! = 1. # Store the only permutation as an immutable string, not a mutable list. if i >= len(s) - 1: return ["".join(s)] # Inductive Step: (len(s) - i)! = (len(s) - i) * (len(s) - i - 1)! # Swap in each suffix character to be at the beginning of the suffix. perms = get_perms(s, i + 1) for j in range(i + 1, len(s)): s[i], s[j] = s[j], s[i] perms.extend(get_perms(s, i + 1)) s[i], s[j] = s[j], s[i] return perms
sumber
Namun inisiatif lain dan solusi rekursif. Idenya adalah memilih huruf sebagai poros dan kemudian membuat kata.
# for a string with length n, there is a factorial n! permutations alphabet = 'abc' starting_perm = '' # with recursion def premuate(perm, alphabet): if not alphabet: # we created one word by using all letters in the alphabet print(perm + alphabet) else: for i in range(len(alphabet)): # iterate over all letters in the alphabet premuate(perm + alphabet[i], alphabet[0:i] + alphabet[i+1:]) # chose one letter from the alphabet # call it premuate(starting_perm, alphabet)
Keluaran:
sumber
Ini adalah versi generator yang sangat sederhana:
def find_all_permutations(s, curr=[]): if len(s) == 0: yield curr else: for i, c in enumerate(s): for combo in find_all_permutations(s[:i]+s[i+1:], curr + [c]): yield "".join(combo)
Saya pikir itu tidak terlalu buruk!
sumber
def f(s): if len(s) == 2: X = [s, (s[1] + s[0])] return X else: list1 = [] for i in range(0, len(s)): Y = f(s[0:i] + s[i+1: len(s)]) for j in Y: list1.append(s[i] + j) return list1 s = raw_input() z = f(s) print z
sumber
Berikut adalah implementasi rekursif yang sederhana dan langsung;
def stringPermutations(s): if len(s) < 2: yield s return for pos in range(0, len(s)): char = s[pos] permForRemaining = list(stringPermutations(s[0:pos] + s[pos+1:])) for perm in permForRemaining: yield char + perm
sumber
stringPermutations
dalam daftar - Anda dapat mengulanginya secara langsung, misfor perm in stringPermutations(s[:pos] + s[pos+1:]):
. Juga, Anda dapat menyederhanakanfor
lingkaran dengan menggunakanenumerate
bukanrange
, dan menghilangkanchar = s[pos]
tugas:for pos, char in enumerate(s):
.from itertools import permutations perms = [''.join(p) for p in permutations('ABC')] perms = [''.join(p) for p in permutations('stack')]
sumber
def perm(string): res=[] for j in range(0,len(string)): if(len(string)>1): for i in perm(string[1:]): res.append(string[0]+i) else: return [string]; string=string[1:]+string[0]; return res; l=set(perm("abcde"))
Ini adalah salah satu cara untuk menghasilkan permutasi dengan rekursi, Anda dapat memahami kode dengan mudah dengan mengambil string 'a', 'ab' & 'abc' sebagai input.
Anda mendapatkan semua N! permutasi dengan ini, tanpa duplikat.
sumber
Semua orang menyukai bau kode mereka sendiri. Hanya membagikan yang menurut saya paling sederhana:
def get_permutations(word): if len(word) == 1: yield word for i, letter in enumerate(word): for perm in get_permutations(word[:i] + word[i+1:]): yield letter + perm
sumber
Program ini tidak menghilangkan duplikat, tetapi menurut saya ini adalah salah satu pendekatan yang paling efisien:
s=raw_input("Enter a string: ") print "Permutations :\n",s size=len(s) lis=list(range(0,size)) while(True): k=-1 while(k>-size and lis[k-1]>lis[k]): k-=1 if k>-size: p=sorted(lis[k-1:]) e=p[p.index(lis[k-1])+1] lis.insert(k-1,'A') lis.remove(e) lis[lis.index('A')]=e lis[k:]=sorted(lis[k:]) list2=[] for k in lis: list2.append(s[k]) print "".join(list2) else: break
sumber
def permute_all_chars(list, begin, end): if (begin == end): print(list) return for current_position in range(begin, end + 1): list[begin], list[current_position] = list[current_position], list[begin] permute_all_chars(list, begin + 1, end) list[begin], list[current_position] = list[current_position], list[begin] given_str = 'ABC' list = [] for char in given_str: list.append(char) permute_all_chars(list, 0, len(list) -1)
sumber
Solusi yang lebih sederhana menggunakan permutasi.
from itertools import permutations def stringPermutate(s1): length=len(s1) if length < 2: return s1 perm = [''.join(p) for p in permutations(s1)] return set(perm)
sumber
Semua Kemungkinan Kata dengan tumpukan
from itertools import permutations for i in permutations('stack'): print(''.join(i))
permutations(iterable, r=None)
Kembalikan permutasi panjang r elemen yang berurutan dalam iterable.
Jika r tidak ditentukan atau Tidak ada, maka r default ke panjang iterable dan semua kemungkinan permutasi panjang penuh dihasilkan.
Permutasi dipancarkan dalam urutan leksikografik. Jadi, jika input iterable diurutkan, permutasi tupel akan diproduksi dalam urutan yang diurutkan.
Elemen diperlakukan sebagai unik berdasarkan posisinya, bukan nilainya. Jadi jika elemen inputnya unik, tidak akan ada nilai pengulangan di setiap permutasi.
sumber
Ini adalah solusi rekursif
n!
yang menerima elemen duplikat dalam stringimport math def getFactors(root,num): sol = [] # return condition if len(num) == 1: return [root+num] # looping in next iteration for i in range(len(num)): # Creating a substring with all remaining char but the taken in this iteration if i > 0: rem = num[:i]+num[i+1:] else: rem = num[i+1:] # Concatenating existing solutions with the solution of this iteration sol = sol + getFactors(root + num[i], rem) return sol
Saya memvalidasi solusi dengan mempertimbangkan dua elemen, jumlah kombinasi adalah
n!
dan hasilnya tidak boleh mengandung duplikat. Begitu:inpt = "1234" results = getFactors("",inpt) if len(results) == math.factorial(len(inpt)) | len(results) != len(set(results)): print("Wrong approach") else: print("Correct Approach")
sumber
Dengan pendekatan rekursif.
def permute(word): if len(word) == 1: return [word] permutations = permute(word[1:]) character = word[0] result = [] for p in permutations: for i in range(len(p)+1): result.append(p[:i] + character + p[i:]) return result running code. >>> permute('abc') ['abc', 'bac', 'bca', 'acb', 'cab', 'cba']
sumber
# swap ith and jth character of string def swap(s, i, j): q = list(s) q[i], q[j] = q[j], q[i] return ''.join(q) # recursive function def _permute(p, s, permutes): if p >= len(s) - 1: permutes.append(s) return for i in range(p, len(s)): _permute(p + 1, swap(s, p, i), permutes) # helper function def permute(s): permutes = [] _permute(0, s, permutes) return permutes # TEST IT s = "1234" all_permute = permute(s) print(all_permute)
# swap ith and jth character of string def swap(s, i, j): q = list(s) q[i], q[j] = q[j], q[i] return ''.join(q) # iterative function def permute_using_stack(s): stk = [(0, s)] permutes = [] while len(stk) > 0: p, s = stk.pop(0) if p >= len(s) - 1: permutes.append(s) continue for i in range(p, len(s)): stk.append((p + 1, swap(s, p, i))) return permutes # TEST IT s = "1234" all_permute = permute_using_stack(s) print(all_permute)
# swap ith and jth character of string def swap(s, i, j): q = list(s) q[i], q[j] = q[j], q[i] return ''.join(q) # finds next lexicographic string if exist otherwise returns -1 def next_lexicographical(s): for i in range(len(s) - 2, -1, -1): if s[i] < s[i + 1]: m = s[i + 1] swap_pos = i + 1 for j in range(i + 1, len(s)): if m > s[j] > s[i]: m = s[j] swap_pos = j if swap_pos != -1: s = swap(s, i, swap_pos) s = s[:i + 1] + ''.join(sorted(s[i + 1:])) return s return -1 # helper function def permute_lexicographically(s): s = ''.join(sorted(s)) permutes = [] while True: permutes.append(s) s = next_lexicographical(s) if s == -1: break return permutes # TEST IT s = "1234" all_permute = permute_lexicographically(s) print(all_permute)
sumber