我需要输入一个字符串,并返回其下一个按字典顺序排列的字符串。例如,下一个'anmdfg'字符串是'anmdgf'。但是,输入的长度可能非常大,可能包含100个字符或者更多,并且会有一些重复的字符。所以我决定使用itertools.permutations而不将其放入列表中以避免内存过度消耗。
#!/usr/bin/env python3
from itertools import permutations
a = list(input())
tuple_a = tuple(a)
b = permutations(a,len(a))
p = next(b)
result = ''
try:
while 1:
p = next(b)
if p > tuple_a:
result = ''.join(p)
print(result)
break
except:
if result == '':
print('No answer.')
else:
if result == '':
print('No answer.')
我的样本中的b没有排序。似乎我必须首先生成列表。我尝试过,它耗尽了我的记忆,所以我没有时间终止这个过程。 有没有办法让我在没有列表的情况下对排列结果进行排序?
答案 0 :(得分:1)
实际上,确实效率低,无法生成低于输出的所有排列。最好使用下面实现的classic linear-time algorithm:
def nextperm(lst):
for i in range(len(lst) - 1, 0, -1):
if lst[i-1] < lst[i]:
for j in range(len(lst) - 1, i-1, -1):
if lst[i-1] < lst[j]:
return lst[:i-1] + lst[j:j+1] + lst[:j:-1] + lst[i-1:i] + lst[j-1:i-1:-1]
答案 1 :(得分:0)
我认为itertools
- y的方法是:
from itertools import dropwhile, permutations
def next_largest(start):
"""Return the next largest permutation of the characters in start."""
reference = tuple(start)
try:
return next(dropwhile(
lambda p: p <= reference,
permutations(sorted(start))
))
except StopIteration:
raise ValueError('No larger string available')
请注意,在生成排列之前对start
进行排序,以确保按字典顺序生成排列。
另请注意:
except:
");和next(thing)
而不是thing.__next__()
(请参阅What is the relationship between the Python data model and built-in functions?)。答案 2 :(得分:0)
试试这个,
-lz and -lgdi32
答案 3 :(得分:0)
通用方法是:
以下是实现该目标的代码:
>>> from itertools import permutations
>>> my_string = 'anmdfg'
# Permutation of all the strings
>>> all_strings = list(permutations(my_string, len(my_string)))
# Sorted lexicographically
>>> all_string = sorted(all_strings)
# index of current string
>>> my_index = all_string.index(tuple(my_string))
# Next item (but as tuple)
>>> next_value = all_string[my_index+1]
>>> next_value
('a', 'n', 'm', 'd', 'g', 'f')
# Convert tuple to string
>>> ''.join(next_value)
'anmdgf'
答案 4 :(得分:0)
使用python生成下一个排列的相对简单的实现。
def nextperm(s):
l=[]
for i in range(len(s)):
l.append(s[i])
for i in range(-1,-len(s),-1):
if (l[i] > l[i-1]):
break
else:
pass
pos=len(s)+(i-1)
for i in range(pos,len(s),1):
if (l[pos] > l[i]):
(l[pos],l[i-1])=(l[i-1],l[pos])
break
else:
pass
l=l[:pos+1]+l[-1:-(len(s)-pos):-1]
s1=''.join(l)
return(s1)