如果要查看以1种方式组合从1到N的数字的方式如何,那么通过使用加法或减法,您将得到等于给定目标数字的组合。
关于该主题Finding all possible combinations of numbers to reach a given sum,我无法以可以达到预期效果的方式对其进行修改,因此我决定去询问。
示例:(让我们说N =8。如果我创建以下从1到N的数组,该如何解决这个问题。不要重复使用每个数字。)
结果:
答案 0 :(得分:3)
这里有一个递归函数,它将打印所有有效的组合和无效的组合。
// This code can be improved a lot, but i wrote it in the way that i believe it is easier to read and understand what it does.
using System;
namespace algorithm_simple_csharp
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Working on it!");
int[] allNumbers = new int[] {1,2,3,4};
int desiredSum = 0;
// We will create two trees, one with a positive first number, and the other one with a negative one
// Positive tree
int initIndex = 0;
OperationTreeNode firstPositiveNode = new OperationTreeNode
{
parentNode = null,
currentNumber = allNumbers[initIndex],
accumulativeSum = allNumbers[initIndex],
operation = "+"
};
int totalSolutionsPositiveFirst = ApplyNumber(firstPositiveNode, allNumbers, initIndex + 1, desiredSum);
// Negative tree
OperationTreeNode firstNegativeNode = new OperationTreeNode
{
parentNode = null,
currentNumber = -allNumbers[initIndex],
accumulativeSum = -allNumbers[initIndex],
operation = "-"
};
int totalSolutionsNegativeFirst = ApplyNumber(firstNegativeNode, allNumbers, initIndex + 1, desiredSum);
// Print all solutions found with both trees
Console.WriteLine("Total soltions: " + (totalSolutionsPositiveFirst + totalSolutionsNegativeFirst));
}
// This function will take care of the next number we should apply: allNumbers[index]
// If there are still numbers to apply, It will create two nodes, one for + allNumbers[index] and one for - allNumbers[index]
static int ApplyNumber(OperationTreeNode currentNode, int[] allNumbers, int index, int desiredSum)
{
// The base case, There are no more numbers to cover.
// In that case we evaluate if the last node is equal to desiredSum or not
if(index > allNumbers.GetUpperBound(0))
{
if(currentNode.accumulativeSum == desiredSum)
{
Console.WriteLine(currentNode.BranchToString() + " = " + currentNode.accumulativeSum + " <--- THIS ONE");
return 1;
}
Console.WriteLine(currentNode.BranchToString() + " = " + currentNode.accumulativeSum);
return 0;
}
// If it is not the last node, then we create two child nodes of the current node.
// First we evaluate what happens if we apply a + to the next number...
OperationTreeNode plusNode = new OperationTreeNode
{
parentNode = currentNode,
currentNumber = allNumbers[index],
accumulativeSum = currentNode.accumulativeSum + allNumbers[index],
operation = "+"
};
int totalSolutionsWithPlus = ApplyNumber(plusNode, allNumbers, index +1, desiredSum);
// Now we evaluate what happens if we apply a - to the next number...
OperationTreeNode minusNode = new OperationTreeNode
{
parentNode = currentNode,
currentNumber = allNumbers[index],
accumulativeSum = currentNode.accumulativeSum - allNumbers[index],
operation = "-"
};
int totalSolutionsWithMinus = ApplyNumber(minusNode, allNumbers, index +1, desiredSum);
// The total number of solutions we found is the sum of the solutions of both sub-trees
return totalSolutionsWithPlus + totalSolutionsWithMinus;
}
}
public class OperationTreeNode
{
public int accumulativeSum = 0;
public OperationTreeNode parentNode = null;
public int currentNumber = 0;
public string operation;
public string BranchToString()
{
if(parentNode == null)
{
return $"{this.currentNumber} ";
}
return $"{parentNode.BranchToString()} {this.operation} {this.currentNumber} ";
}
}
}
Working on it!
1 + 2 + 3 + 4 = 10
1 + 2 + 3 - 4 = 2
1 + 2 - 3 + 4 = 4
1 + 2 - 3 - 4 = -4
1 - 2 + 3 + 4 = 6
1 - 2 + 3 - 4 = -2
1 - 2 - 3 + 4 = 0 <--- THIS ONE
1 - 2 - 3 - 4 = -8
-1 + 2 + 3 + 4 = 8
-1 + 2 + 3 - 4 = 0 <--- THIS ONE
-1 + 2 - 3 + 4 = 2
-1 + 2 - 3 - 4 = -6
-1 - 2 + 3 + 4 = 4
-1 - 2 + 3 - 4 = -4
-1 - 2 - 3 + 4 = -2
-1 - 2 - 3 - 4 = -10
Total soltions: 2
它创建一棵树。树的每个节点都是OperationTreeNode
类型的对象,代表一个数字及其操作。例如:+1和-1是两个OperationTreeNode
当您到达最后一个数字时,ApplyNumber
将评估该节点是否等于desiredSum
。
ApplyNumber
返回子树找到的解决方案
答案 1 :(得分:0)
据我所知,如果我已经理解了这个问题,则需要一个for
循环,因为如果您有一个数字n
,则存在无限数量的数字加或减组合n
,因此您需要一个数字,如果达到该数字将停止该过程。
如果您需要多个数字(例如3 + 10 + 1 = 14),则需要更多循环。
这就是我要走的路:
int l = 50;//my limit
int n = 14;//my number
for(int i = 0; i < l; i++)
{
for(int j = 0; j < l; j++)
{
if ( i + j == n )
{
//Do whatever you want
Console.WriteLine("{0} = {1} + {2}", n, i, j);
}
if ( i - j == n )
{
//Do whatever you want
Console.WriteLine("{0} = {1} - {2}", n, i, j);
}
}
}//Repeat for negative numbers
希望这会有所帮助。
答案 2 :(得分:0)
反复尝试,有多少种方法可以达到目标。
using System;
class Program
{
static void Main()
{
Console.WriteLine(C(0));
int[] a = { 1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121, 144 };
Console.Write(C(0, a)); Console.Read();
}
static int C(int t) // ±1 ± 2 ± 3 ± 4 == 0
{
int c = 0, s = 0;
for (int n = 0; n < 16; n++)
{
if ((n & 1) == 0) s -= 1; else s += 1;
if ((n & 2) == 0) s -= 2; else s += 2;
if ((n & 4) == 0) s -= 3; else s += 3;
if ((n & 8) == 0) s -= 4; else s += 4;
if (s == t) c++; s = 0;
} return c;
}
static int C(int t, int[] a)
{
int c = 0, s = 0, i, j = a.Length, n, m = 1 << j;
for (n = 0; n < m; n++)
{
for (i = 0; i < j; i++)
if ((n & 1 << i) == 0) s -= a[i]; else s += a[i];
if (s == t) c++; s = 0;
} return c;
}
}