파이썬에서 주어진 문자열의 가능한 모든 순열 찾기


89

나는 문자열이 있습니다. 문자열의 문자 순서를 변경하여 해당 문자열에서 모든 순열을 생성하고 싶습니다. 예를 들면 다음과 같습니다.

x='stack'

내가 원하는 것은 이와 같은 목록입니다.

l=['stack','satck','sackt'.......]

현재 나는 문자열의 목록 캐스트를 반복하고, 무작위로 2 개의 문자를 선택하고이를 조옮김하여 새 문자열을 형성하고 l의 캐스트를 설정하기 위해 추가합니다. 문자열의 길이에 따라 가능한 순열 수를 계산하고 설정된 크기가 한계에 도달 할 때까지 반복을 계속합니다. 더 나은 방법이 있어야합니다.

답변:


143

itertools 모듈에는 permutations ()라는 유용한 메소드가 있습니다. 문서 는 다음과 같이 말합니다.

itertools.permutations (iterable [, r])

반복 가능한 요소의 연속 r 길이 순열을 반환합니다.

r이 지정되지 않았거나 None이면 r은 기본적으로 iterable의 길이로 설정되고 가능한 모든 전체 길이 순열이 생성됩니다.

순열은 사전 식 정렬 순서로 생성됩니다. 따라서 입력 iterable이 정렬되면 순열 튜플이 정렬 된 순서로 생성됩니다.

하지만 순열 된 문자를 문자열로 결합해야합니다.

>>> from itertools import permutations
>>> perms = [''.join(p) for p in permutations('stack')]
>>> perms

[ '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 ']

중복으로 인해 문제가 발생하면 set다음 과 같은 중복이없는 구조에 데이터를 맞추십시오 .

>>> perms = [''.join(p) for p in permutations('stacks')]
>>> len(perms)
720
>>> len(set(perms))
360

이것이 우리가 전통적으로 타입 캐스트라고 생각하는 것이 아니라 set()생성자 에 대한 호출에 더 가깝다는 것을 지적 해준 @pst에게 감사드립니다 .


3
Nit : set(...)"캐스트"하지 않습니다. 오히려 입력 컬렉션을 나타내는 집합을 생성 (및 생성)합니다. 일단 생성되면 입력 컬렉션과 연결되지 않습니다 (단지 다른 뷰가 아닌 다른 개체 임).

@pst : 흠 나는 동의하지 않는 경향이 있습니다. 나는 Ada 또는 Pascal에서 캐스트가 동일한 비트에 대한 새로운 유형 뷰라는 것을 알고 있습니다. 그러나 적어도 C 관점에서 캐스팅은 데이터의 기본 구조를 변경하는지 여부에 관계없이 적절한 용어입니다. 단순히 명시 적 유형 변환을 나타냅니다. 가능하다면 내 오해를 설명해주세요.
기계 그리움

1
형변환 . 아시다시피 단순한 관점과는 다를 수 있지만 혼란을 피하기 위해 개념을 분리하여 유지하는 것을 좋아합니다. 첫 번째 주석에서 명시 적으로 "강제"를 언급 했어야했는데, 함수 설정 : list-> set 만 고려할 것입니다.

1
나는 그것이 입력 에 따라 부울 (True / False)로 평가bool 되는 함수 라고 봅니다 . 나는 "캐스트"의 사용을 찾을 여기 ... 가짜와 오해의 소지가있다

1
흥미로운 업데이트로 문서는 그 이후로 The built-in function bool () can be used to convert any value to Boolean , 특히 변환보다는 캐스트로 변경되었습니다. 이것은이 토론의 후속 릴리스에서 발생했으며이 토론이 문서의 변경으로 이어진다 고 믿게했습니다!
2015 년

45

모든 N을 얻을 수 있습니다! 많은 코드가없는 순열

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)

좋은 사람. 완벽하게 작동합니다
kishorer747 2014

1
약간 수정했습니다. i == 단계 인 경우 변수를 바꿀 필요가 없습니다.
siraj

4
n!이 있으므로 런타임은 O (n!)입니다. 순열.
아스펜

step == len(string)대신 왜 사용 하고 step == len(string) - 1있습니까?
tulians

그러면 마지막 2 개 항목은 절대로 교환되지 않습니다. b와 c가 바뀔 때까지 'abc'를 시도하십시오.
Roman Riesen

14

다음은 최소한의 코드로 문자열 순열을 수행하는 또 다른 방법입니다. 우리는 기본적으로 루프를 만든 다음 한 번에 두 문자를 계속 교체합니다. 루프 내부에는 재귀가 있습니다. 인덱서가 문자열 길이에 도달 할 때만 인쇄합니다. 예 : 시작점을위한 ABC i와 루프를위한 재귀 매개 변수 j

여기에 왼쪽에서 오른쪽으로 위에서 아래로 어떻게 작동하는지 시각적 인 도움말이 있습니다 (순열 순서).

여기에 이미지 설명 입력

코드 :

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)

5
이것이 bactracking 패러다임 의 기초라는 것을 언급하는 것이 도움이 될 수 있습니다 .
AruniRC

더 많은 정보, 동일 / 유사한 코드 : geeksforgeeks.org/… 그래픽 예제를 사용하면 귀하의 예제가 더 좋습니다.)
CTS_AE

8

Stack Overflow 사용자는 이미 강력한 솔루션을 게시했지만 또 다른 솔루션을 보여주고 싶었습니다. 이건 더 직관적 인 것 같아요

아이디어는 주어진 문자열에 대해 알고리즘 (의사 코드)에 의해 재귀 할 수 있다는 것입니다.

순열 = char + 문자열의 char에 대한 순열 (문자열-문자)

누군가에게 도움이되기를 바랍니다!

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

4
반복되는 문자 (str.replace)가있는 경우에는 작동하지 않습니다. 예 : rqqx
sanjay

사용 : [permutation_list.append (char + a) for a in permutations (string.replace (char, "", 1))]
user3761855

7

다음은 고유 한 순열을 반환하는 간단한 함수입니다.

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)

6
1. 오타가 있습니다 : revursive_perms-> recursive_perms. 2. recursive_permsreturn 문에서 집합으로 변환하는 목록이 아닌 집합 이면 RAM과 시간을 절약 할 수 있습니다. 3. .replace의 재귀 호출에 대한 인수를 구성하는 대신 문자열 슬라이싱을 사용하는 것이 더 효율적 입니다 permutations. 4. string표준 string모듈 의 이름을 가리기 때문에 변수 이름 으로 사용하는 것은 좋은 생각이 아닙니다 .
PM 2Ring

5

@Adriano 및 @illerucis가 게시 한 것과 다른 접근 방식이 있습니다. 이것은 더 나은 런타임을 가지고 있으며 시간을 측정하여 직접 확인할 수 있습니다.

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

임의의 문자열 "dadffddxcf"의 경우 순열 라이브러리의 경우 1.1336 초,이 구현의 경우 9.125 초, @Adriano 및 @illerucis 버전의 경우 16.357 초가 소요되었습니다. 물론 여전히 최적화 할 수 있습니다.


4

itertools.permutations좋지만 반복되는 요소를 포함하는 시퀀스를 잘 처리하지 못합니다. 내부적으로 시퀀스 인덱스를 순열하고 시퀀스 항목 값을 알지 못하기 때문입니다.

물론, itertools.permutations세트를 통해 출력을 필터링하여 중복을 제거 할 수 있지만 여전히 중복을 생성하는 데 시간을 낭비하고 기본 시퀀스에 여러 반복 요소가있는 경우 많은 중복이 있습니다. 또한 컬렉션을 사용하여 결과를 보관하면 RAM이 낭비되어 처음부터 반복기를 사용하는 이점이 무효화됩니다.

다행히 더 효율적인 접근 방식이 있습니다. 아래 코드는 14 세기 인도의 수학자 Narayana Pandita의 알고리즘을 사용합니다.이 알고리즘은 Permutation 에 대한 Wikipedia 기사에서 찾을 수 있습니다 . 이 고대 알고리즘은 순서대로 순열을 생성하는 가장 빠른 방법 중 하나이며 반복되는 요소를 포함하는 순열을 적절하게 처리한다는 점에서 매우 강력합니다.

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)

산출

aadt
aatd
adat
adta
atad
atda
daat
data
dtaa
taad
tada
tdaa

물론 산출 된 문자열을 목록으로 수집하려면 다음을 수행 할 수 있습니다.

list(lexico_permute_string('data'))

또는 최신 Python 버전 :

[*lexico_permute_string('data')]

아름답게 설명되었습니다.
lmao

2

왜 간단하지 않습니까?

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))

보시다시피 중복되지 않습니다.

 ['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]

4
아니요, 두 개 이상의 동일한 문자가 있으면 항상 중복 (또는 더 나쁜)을받습니다. 그는 단어의 사용 즉, @ machineyearning의 예에서의 경우와 스택 대신 스택 . 즉, 솔루션은 고유 한 문자가 포함 된 단어에 대해서만 작동합니다.
erik

2
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')))

2
귀하의 솔루션이 이미 제공된 솔루션보다 나은 이유를 설명해 주시겠습니까?
Noel Widmer

내 솔루션이 다른 솔루션보다 낫다고 말하지 않았습니다. 나는 그것을 할 내 솔루션을 제공했습니다.
Srivastava


1

다음은 itertools를 사용하지 않고 고유 한 문자 가있는 문자열의 모든 순열 목록을 반환 하는 약간 개선 된 버전의 illerucis 코드입니다 s.

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

1

또 다른 이니셔티브이자 재귀 적 솔루션입니다. 아이디어는 문자를 피벗으로 선택한 다음 단어를 만드는 것입니다.

# 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)

산출:

abc
acb
bac
bca
cab
cba

0

다음은 정말 간단한 생성기 버전입니다.

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)

그렇게 나쁘지 않다고 생각합니다!


0
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

설명을 추가해주세요.
Arun Vinoth

0
from itertools import permutations
perms = [''.join(p) for p in permutations('ABC')]

perms = [''.join(p) for p in permutations('stack')]

5
설명을 추가해주세요.
Arun Vinoth

0
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"))

이것은 재귀를 사용하여 순열을 생성하는 한 가지 방법입니다. 'a', 'ab'및 'abc'문자열을 입력으로 사용하여 코드를 쉽게 이해할 수 있습니다.

당신은 모두 N을 얻습니다! 중복되지 않은 순열.


0

누구나 자신의 코드 냄새를 좋아합니다. 내가 찾은 가장 간단한 것을 공유하십시오.

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

0

이 프로그램은 중복을 제거하지 않지만 가장 효율적인 접근 방식 중 하나라고 생각합니다.

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

0
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)

설명을 추가해주세요.
Arun Vinoth

0

순열을 사용하는 더 간단한 솔루션.

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)

0

스택이있는 모든 가능한 단어

from itertools import permutations
for i in permutations('stack'):
    print(''.join(i))
permutations(iterable, r=None)

반복 가능한 요소의 연속 r 길이 순열을 반환합니다.

r이 지정되지 않았거나 None이면 r은 기본적으로 iterable의 길이로 설정되고 가능한 모든 전체 길이 순열이 생성됩니다.

순열은 사전 식 정렬 순서로 생성됩니다. 따라서 입력 iterable이 정렬되면 순열 튜플이 정렬 된 순서로 생성됩니다.

요소는 가치가 아닌 위치에 따라 고유 한 것으로 취급됩니다. 따라서 입력 요소가 고유하면 각 순열에 반복 값이 없습니다.


0

이것은 n!문자열에서 중복 요소를 허용 하는 재귀 솔루션입니다.

import 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

두 가지 요소를 고려하여 솔루션의 유효성을 검사했습니다. 조합의 수는 n!중복을 포함 할 수 없습니다. 그래서:

inpt = "1234"
results = getFactors("",inpt)

if len(results) == math.factorial(len(inpt)) | len(results) != len(set(results)):
    print("Wrong approach")
else:
    print("Correct Approach")

-1

다음은 간단하고 직접적인 재귀 구현입니다.

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

1
들여 쓰기를 수정해야합니다. 재귀 호출의 결과를 stringPermutations목록 에 저장할 필요가 없습니다 for perm in stringPermutations(s[:pos] + s[pos+1:]):. 예를 들어 . 또한 대신을 for사용하여 루프를 단순화 하고 할당을 제거 할 수 있습니다 .. enumeraterangechar = s[pos]for pos, char in enumerate(s):
PM 2Ring

-1

재귀 사용

# 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)
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.