我有一个容易看的数学问题。 这是一个数组。
数组= {1,2,3}
需要上述数组元素的所有可能组合,这将使总和= 5。
解决方案:{1,1,1,1,1} {1,1,1,2} {1,2,2} {2,3} {1,1,3}
注意:如果总和应为5,您可以多次使用任何数组元素。
int weight = 5;
List<int> weights = new List<int>() { 1, 2 ,3};
void function1(int weight,List<int> weights, List<List<int>> combinationlist)
{
for (int i = 0; i < weights.Count; i++)
{
if (weight % weights[i] == 0)
{
int num = weight / weights[i];
List<int> mylist = new List<int>();
for (int j = 0; j < num; j++)
{
mylist.Add(weights[i]);
}
if (!combinationlist.Contains(mylist))
combinationlist.Add(mylist);
}
}
}
现在上面的函数生成了{1,1,1,1,1}解的简单组合。
void function2(int weight, List<int> weights, List<List<int>> combinationlist)
{
int i = weights.Count - 1;
Stack<int> mystack = new Stack<int>();
List<int> combinationarray = new List<int>();
foreach (var x in weights)
mystack.Push(x);
for (;i >= 0; i--)
{
if (weight <= weights[i])
mystack.Pop();
}
int remainder = 0;
if (weight % mystack.Peek() != 0)
remainder = weight % mystack.Peek();
int quotient = weight / mystack.Peek();
combine(combinationlist,combinationarray,mystack,quotient,remainder);
}
组合功能
void combine(List<List<int>>combinations,List<int>combination,Stack<int> mystack,int quotient, int remweight)
{
for (int i = 0; i < quotient; i++)
{
combination.Add(mystack.Peek());
}
if (remweight > 1)
remweight = remweight - mystack.Peek() * quotient;
else if (remweight == 0)
{
if (!combinations.Contains(combination))
combinations.Add(combination);
return;
}
else
return;
while (mystack.Peek() > remweight )
{
if (mystack.Count != 0)
mystack.Pop();
}
quotient = remweight / mystack.Peek();
combine(combinations, combination, mystack, quotient, remweight);
}
完成所有工作。我只能得到两个解决方案{2,1,1,1} {1,1,1,1,1}。
答案 0 :(得分:0)
我将在python中提供一个答案,因为它很好地说明了算法。 Python几乎就像这些问题的伪代码一样。
# curr: a temporary list that is used only for printing the result
# arr: the list of input values
# val: the number we want to sum to
# currval: the number used so far (that will be the maximum number used so far)
def recursive_combos(curr, arr, val, currval):
for item in arr:
if item < currval:
continue
if val - item < 0:
return
if val - item == 0:
print curr + [item]
continue
recursive_combos(curr + [item], arr, val - item, item)
return
def combos(arr, val):
recursive_combos([], sorted(arr), 5, min(arr) - 1)
combos([3, 1, 2], 5)
答案:
[1, 1, 1, 1, 1]
[1, 1, 1, 2]
[1, 1, 3]
[1, 2, 2]
[2, 3]
这是递归的基本说明,我认为代码大多是不言自明的。
此解决方案中需要注意的关键事项是:
答案 1 :(得分:0)
以下方法简化并获取所有解决方案(代码采用Racket编程语言)。评论解释了正在进行的程序:
(define L '(0 1 2 3)) ; ADD 0 TO THE LIST;
(define outl
(for*/list ( ; TRY ALL COMBINATIONS CHOOSING 5 NUMBERS FROM ABOVE LIST;
; SINCE THAT IS MAXIMUM NUMBER OF ELEMENTS THAT CAN ADD UP TO 5;
; REPETITION IS ALLOWED;
(i L)
(j L)
(k L)
(m L)
(n L)
#:when (= 5 (+ i j k m n))) ; USE COMBINATION ONLY IF SUM IS 5;
(remove* (list 0) ; REMOVE 0s FROM THIS COMBINATION;
(sort (list i j k m n) <)))) ; SORT COMBINATION;
(remove-duplicates outl) ; REMOVE DUPLICATES FROM LIST;
输出是答案列表列表:
'((2 3) (1 1 3) (1 2 2) (1 1 1 2) (1 1 1 1 1))
另一个解决方案是使用递归来保持添加所有元素,直到达到(或超过)总和:
(define L '(1 2 3))
(define desired_sum 5)
(define anslist '()) ; solutions will be added to this list;
(let loop ((ol '())) ; start with an empty list;
(for ((i L)) ; try adding each element and see if desired sum is reached;
(cond
[(= desired_sum (apply + (cons i ol))) ; desired sum reached
(set! anslist ; add sorted solution to anslist;
(cons (sort (cons i ol) <) ; sorting needed to identify duplicates later;
anslist))]
[(> desired_sum (apply + (cons i ol))) ; total is less than desired sum
(loop (cons i ol))] ; so loop again to add more elements;
))) ; discard (no looping) if desired sum is exceeded;
(remove-duplicates anslist) ; print after removing duplicate solutions;
输出:
'((2 3) (1 1 3) (1 2 2) (1 1 1 2) (1 1 1 1 1))