Здесь рекурсивная функция, которая будет печатать все комбинации, которые работали, и те, которые не работали.
Код (протестируйте его здесь , или более простую версию здесь ):
// 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
возвращает количество решений, найденных поддеревом