[英]Generate unique combinations of length k from string
假设我们有字符串aabc
。 如果你从这个字符串中取出两个字符而不进行替换,你的结果将在集合{aa, ab, ac, bc}
中。 我正在尝试开发一种算法来构建这个集合。 重要的是没有重复项。 如果所有字符都是唯一的,则算法很简单,但如果存在重复,则算法会变得更加复杂。 我想出了这个,但我很好奇是否有更简单的解决方案:
from collections import Counter
class Solution(object):
def combinations(self, s, k):
s = Counter(s)
self.res = []
self.combo_helper('', s, k)
return self.res
def combo_helper(self, used, remaining, k):
if k == 0:
self.res.append(used)
else:
new = remaining.copy()
for n in remaining:
if remaining[n]:
new[n] -= 1
self.combo_helper(
used+n, new, k-1
)
new = new.copy()
new[n] = 0
我采纳了@Pychopath 的建议并检查了解决问题的more-itertools
方法。 他们采用自下而上的 DP 方法,我想我会把它转换回我最初采用的自上而下的方法。 不幸的是,它要求您先对可迭代对象进行排序
class Solution:
def first_char_idx(self, s, start=0):
''''
Returns first idx and char of string
aabbc -> [(0, a), (2, b), (4, c)]
'''
seen = set()
return [(idx, c) for idx, c in enumerate(s, start) if c not in seen and not seen.add(c)]
def unique_combos_helper(self, used, idx, k):
if not k:
self.res.append(used)
else:
for i, c in self.first_char_idx(self.pool[idx:], idx):
self.unique_combos_helper(used+c, i+1, k-1)
def unique_combos(self, s, k):
s = sorted(list(s))
self.res = []
self.pool = s
self.unique_combos_helper("", 0, k)
return self.res
一个集合不允许重复,所以,你可以把它作为一个列表来做,然后转换成一个集合。
在一个列表中,有重复项,你的结果采用所有可能性将重复['aa', 'ab', 'ac', 'ab', 'ac', 'bc']
,但如果你转换做一个集合,它不会:
x='aabc'
b=list()
for i in range(len(x)-1):
for j in range(i+1,len(x)):
b.append(x[i]+x[j])
b=set(b)
根据您的需要更改长度:
import itertools
list='aabc'
lenght=2
result=[''.join(p) for p in itertools.product(list, repeat=lenght)][::-1]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.