簡體   English   中英

結合使用重復的字母和列表中的權重

[英]Combinations with repetition of letters with weight from list

我有四個不同權重的字母

letters = ['C', 'N', 'O', 'S']
weights_of_l = [1, 1, 2, 2]

我想得到weight = 2的字母組合。 字母可以反復選擇,順序並不重要。 結果可以是列表或數組或任何形式,但具有此組合

comb_w2 = ['CC','NN','NC','O','S']

這里CN weight = 1所以將兩個字母組合起來的weight = 2 :可能的組合是'CC','NN','NC'

OS已經具有weight = 2因此它不能與其他字母結合。 是否有用於計算此值的庫? 我看到了itertools但它只給出了可能性的數量,而沒有給出組合的可能性。

您的問題是分區 (不是一件容易的事)。 您可以使用帖子針對給定的權重生成所有可能的組合結果。 然后,您可以刪除那些在weights_of_l沒有的鍵。 最后,將數字替換為字母,並為它們創建具有相同權重的字母的排列。

@Sneha的回答很簡潔明了,但是如果您要使用很多組合,那么最好不要過多地創建組合。 此解決方案更長,但對於目標得分高的字母較長的列表,運行速度更快:

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

我的答案最終與特克薩拉瑪的答案非常相似。 即,如果需要結果的組合,則必須對字母進行排序並使用一組字符來消除重復項。 我的方法更簡潔,但是需要通過函數調用來調用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)))

創建字母的所有組合,並使用過濾器功能刪除組合權重不等於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或所需重量的字母,然后創建所有組合。

嘗試以下代碼:

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

這可能不是最好的方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM