我有四个不同重量的字母
letters = ['C', 'N', 'O', 'S']
weights_of_l = [1, 1, 2, 2]
我想获得weight = 2
的字母组合。这封信可以重复选择,订单也不重要。结果可以是列表或数组或任何形式,但使用此组合
comb_w2 = ['CC','NN','NC','O','S']
此处C
和N
有weight = 1
,因此合并两个字母weight = 2
:可能的组合为'CC','NN','NC'
O
和S
已经weight = 2
,因此无法与其他字母合并。有没有计算这个的库?我看到了itertools
,但它只给出了可能性的数量,而不是组合。
答案 0 :(得分:1)
你的问题是partitioning(不容易的事)。
您可以使用this帖子为给定的体重生成所有可能的组合结果。然后,您可以删除包含您在weights_of_l
中没有的密钥的密钥。最后,用字母代替数字,并为具有相同权重的字母创建排列。
答案 1 :(得分:1)
letters = ['C', 'N', 'O', 'S']
weights_of_l = [1, 1, 2, 2]
def get_combos(letters, weights, goal):
weighted_letters = list(zip(letters, weights))
combos = set()
def get_combos(letters, weight):
for letter, next_weight in weighted_letters:
total = weight + next_weight
if total == goal:
combos.add(''.join(sorted(letters + letter)))
elif total > goal:
pass
else:
get_combos(letters + letter, weight+next_weight)
get_combos('',0)
return combos
print(get_combos(letters, weights_of_l, 3))
编辑:我认为这个可能更快:
letters = ['C', 'N', 'O', 'S']
weights_of_l = [1, 1, 2, 2]
def get_combos(letters, weights, goal):
weighted_letters = sorted(zip(weights, letters))
combos = []
def get_combos(letters, weight, weighted_letters):
for i, (next_weight, letter) in enumerate(weighted_letters):
total = weight + next_weight
if total == goal:
combos.append(letters + letter)
elif total > goal:
return
else:
get_combos(letters+letter, weight+next_weight, weighted_letters[i:])
get_combos('',0,weighted_letters)
return combos
print(get_combos(letters, weights_of_l, 3))
答案 2 :(得分:1)
我的答案最终与Turksarama非常相似。也就是说,如果您需要结果组合,则必须对字母进行排序并使用集合来删除重复项。我的方法更简洁,但需要使用函数调用set()
来调用。
letters = ['C', 'N', 'O', 'S']
weights = [1, 1, 2, 2]
items = list(zip(weights, letters))
def combinations(items, max_weight, weight=0, word=''):
if weight == max_weight:
yield ''.join(sorted(word))
items_allowed = [(w, l) for w, l in items if max_weight - weight >= w]
for w, l in items_allowed:
for result in combinations(items_allowed, max_weight, weight+w, word+l):
yield result
print(set(combinations(items, 2)))
答案 3 :(得分:0)
创建字母的所有组合并使用过滤功能删除组合权重不等于2的所有组合。
from itertools import combinations_with_replacement
letters = ['C', 'N', 'O', 'S']
weights_of_l = [1, 1, 2, 2]
y=dict(zip(letters,weights_of_l)) #Creates a dict of the two list letters
#and weights_of_l
print(list(map(lambda x:''.join(x),filter(lambda
x:y[x[0]]+y[x[1]]==2,combinations_with_replacement(letters,2)))))
或者您最初可以过滤字母列表中的所有字母,以包括重量小于2或您需要的重量的字母,然后创建所有组合。
答案 4 :(得分:0)
请尝试以下代码:
def find_combinations(letter_list, weight_list, weignt_sum):
output_list = []
letter_weight_dict = dict(zip(letter_list,weight_list))
for key, val in letter_weight_dict.items():
for key1, val1 in letter_weight_dict.items():
if val+val1 == weignt_sum:
if (key + key1)[::-1] not in output_list:
output_list.append(key+key1)
if val == weignt_sum:
output_list.append(key)
return set(output_list)
letters = ['C', 'N', 'O', 'S']
weights_of_l = [1, 1, 2, 2]
combinations = find_combinations(letters, weights_of_l, 2)
print combinations
我得到了以下输出:
['CC','S','NN','CN','O']
这可能不是最好的方法。