我现在正试图找到总结到特定值的数组的所有元素(包括非连续的):
using System;
namespace ProgrammingBasics
{
class Exercise
{
static void Main()
{
PrintArray(arr);
SubarrayWithSum();
}
//--------------------------------------------------------------------
/*
Data members.
*/
// targer array
static int[] arr = { 2, 1, 2, 4, 3, 5, 2, 6 };
// target sum
static int sum = 14;
//--------------------------------------------------------------------
/*
Method: IsSubarrayWithSum(arr, sum);
It returns a bool value that indicates
whether there is a subarray within arr
with elements that sum up to specific value.
*/
static void SubarrayWithSum()
{
int depth = 0;
int startIndex = 0;
int endIndex = 1;
CheckAllCombinations(new int[arr.Length], startIndex, endIndex, depth);
}
//--------------------------------------------------------------------
/*
Method: CheckAllCombinations(subarray, sum);
*/
static void CheckAllCombinations(int[] subarray, int startIndex, int endIndex, int depth)
{
if (depth >= arr.Length)
{
return;
}
//Console.ReadKey();
for (int i = startIndex; i < endIndex; i++)
{
subarray[i] = arr[i];
//Console.WriteLine("startIndex = {0}, depth = {1}, i = {2}", startIndex, depth, i);
if (IsWantedSum(subarray))
{
Console.Write("S = {0} -> yes", sum);
PrintSubArray(subarray);
}
//PrintArray(subarray);
//Console.ReadKey();
CheckAllCombinations(new int [arr.Length], startIndex += 1, endIndex = (endIndex < arr.Length)? endIndex + 1 : endIndex, depth += 1);
}
}
//--------------------------------------------------------------------
/*
Method: IsWantedSum(int[] arr)
*/
static bool IsWantedSum(int[] arr)
{
int currentSum = 0;
for (int i = 0; i < arr.Length; i++)
{
currentSum += arr[i];
}
if (currentSum == sum)
{
return true;
}
else
{
return false;
}
}
//--------------------------------------------------------------------
/*
Method: PrintArray();
*/
static void PrintArray(int[] subarray)
{
Console.Write("{");
for (int i = 0; i < subarray.Length; i++)
{
Console.Write(subarray[i]);
if (i < subarray.Length -1) Console.Write(", ");
}
Console.WriteLine("}");
}
//--------------------------------------------------------------------
/*
Method: PrintSubArray();
*/
static void PrintSubArray(int[] subarray)
{
Console.Write("(");
for (int i = 0; i < subarray.Length; i++)
{
if (subarray[i] != 0)Console.Write(subarray[i]);
if (subarray[i] != 0 && i < subarray.Length - 1) Console.Write(" + ");
}
Console.WriteLine(" = {0})", sum);
}
}
}
我得到了部分正确的结果:
{2,1,2,4,3,5,2,6}
S = 14 - &gt;是(4 + 3 + 5 + 2 + = 14)
S = 14 - &gt;是(2 + 4 + 3 + 5 + = 14)
S = 14 - &gt;是(4 + 3 + 5 + 2 + = 14)
S = 14 - &gt;是(4 + 3 + 5 + 2 + = 14)
S = 14 - &gt;是(2 + 4 + 3 + 5 + = 14)
S = 14 - &gt;是(4 + 3 + 5 + 2 + = 14)
带有重复和缺少非连续元素的子数组,例如:
是(1 + 2 + 5 + 6 = 14)
有人可以给我一个关于我的算法问题的提示,并可能建议更正/新实施吗?
答案 0 :(得分:1)
这是使用组合进行此操作的简单方法。可能有更好的方法来存储它们(我正在考虑使用字典来编码你已经拥有的所有子总和)。在一天结束时,如果您想要考虑非连续元素,那么您将不得不获得在这种情况下可能的子数组,而不仅仅是查看连续选择。组合算法的功劳归于ojlovecd here。
class Exercise
{
static void Main()
{
PrintArray(arr);
// SubarrayWithSum();
var result = GetCombination(arr);
foreach(var list in result)
{
var total = list.Sum();
if (total == sum)
PrintArray(list);
}
}
static List<int> arr = new List<int> { 2, 1, 2, 4, 3, 5, 2, 6 };
static int sum = 14;
static List<List<int>> GetCombination(List<int> list)
{
var result = new List<List<int>>();
result.Add(new List<int>());
double count = Math.Pow(2, list.Count);
for (int i = 1; i <= count - 1; i++)
{
string str = Convert.ToString(i, 2).PadLeft(list.Count, '0');
for (int j = 0; j < str.Length; j++)
{
if (str[j] == '1')
{
result[i - 1].Add(list[j]);
}
}
result.Add(new List<int>());
}
return result;
}
static void PrintArray(List<int> subarray)
{
Console.Write("{");
for (int i = 0; i < subarray.Count; i++)
{
Console.Write(subarray[i]);
if (i < subarray.Count - 1) Console.Write(", ");
}
Console.WriteLine("}");
}
}
答案 1 :(得分:1)
我认为重复项正在发生,因为您在添加的数组中有零。查看运行速度更快的更新代码。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
namespace ProgrammingBasics
{
class Exercise
{
static void Main()
{
PrintArray(arr);
SubarrayWithSum();
}
//--------------------------------------------------------------------
/*
Data members.
*/
// targer array
static int[] arr = { 2, 1, 2, 4, 3, 5, 2, 6 };
// target sum
static int sum = 14;
//--------------------------------------------------------------------
/*
Method: IsSubarrayWithSum(arr, sum);
It returns a bool value that indicates
whether there is a subarray within arr
with elements that sum up to specific value.
*/
static void SubarrayWithSum()
{
int depth = 0;
int endIndex = arr.Length - 1;
CheckAllCombinations(new int[arr.Length], depth);
}
//--------------------------------------------------------------------
/*
Method: CheckAllCombinations(subarray, sum);
*/
static void CheckAllCombinations(int[] subarray, int depth)
{
//Console.ReadKey();
for (int i = depth; i < arr.Length; i++)
{
subarray[depth] = arr[i];
Console.WriteLine("depth = {0}, i = {1}, array = '{2}' ", depth, i, string.Join(",", subarray.Select(x => x.ToString()).ToArray()));
int currentSum = subarray.Take(depth + 1).Sum();
if (currentSum == sum)
{
Console.Write("S = {0} -> yes : ", sum);
Console.WriteLine(string.Join(",", subarray.Take(depth + 1)));
}
//PrintArray(subarray);
//Console.ReadKey();
if (currentSum < sum)
{
CheckAllCombinations(subarray, depth + 1);
}
}
}
//--------------------------------------------------------------------
/*
Method: IsWantedSum(int[] arr)
*/
//--------------------------------------------------------------------
/*
Method: PrintArray();
*/
static void PrintArray(int[] subarray)
{
Console.Write("{");
for (int i = 0; i < subarray.Length; i++)
{
Console.Write(subarray[i]);
if (i < subarray.Length - 1) Console.Write(", ");
}
Console.WriteLine("}");
}
//--------------------------------------------------------------------
/*
Method: PrintSubArray();
*/
static void PrintSubArray(int[] subarray)
{
Console.Write("(");
for (int i = 0; i < subarray.Length; i++)
{
if (subarray[i] != 0) Console.Write(subarray[i]);
if (subarray[i] != 0 && i < subarray.Length - 1) Console.Write(" + ");
}
Console.WriteLine(" = {0})", sum);
}
}
}
答案 2 :(得分:0)
好的,这是一个小小的尝试,简要描述我为了解问题 1 而实现的信息,并实现了一个基本的解决方案。
事实证明,The Subset Sum Problem被认为是Knapsack Problem的一个特例,我们在其中搜索最大化利润,同时保持名为 weight 在特定的容量下,但在我们的例子中,与每个值相关的利润和权重是相同的。
&#34; 背包问题&#34;中描述了各种出色的解决方案。 - Keller,Pferschy,Pisinger,暂时是我能够实现和理解的最简单的解决方案,而不是带来复杂性和/或功效,看起来像这样:
//--------------------------------------------------------------------
/*
Method: FindSubArray();
Base case: - if current sum == targer sum: print current elements.
- if index == arr.Length: terminate search.
Recursive step:
- do not/select element with index and do not/update the current sum; recursive call with updated current sum and index.
*/
static void FindSubArray(int index, int currentSum, bool[] subArray)
{
// base case
if (currentSum == targetSum)
{
PrintSubArray(subArray);
}
else if (index == arr.Length)
{
return;
}
else
{
// recursive calls
subArray[index] = true;
currentSum += arr[index];
FindSubArray(index + 1, currentSum, subArray);
currentSum -= arr[index]; // restore previous value of the sum signifying: element not selected
subArray[index] = false;
FindSubArray(index + 1, currentSum, subArray);
}
}
其中PrintSubArray(subArray);
打印arr
中标有true
的{{1}}的所有元素。
输出:
{2,1,2,4,3,5,2,6}
S = 14 - &gt;是(2 + 1 + 2 + 4 + 3 + 2 + = 14)
S = 14 - &gt;是(2 + 1 + 2 + 4 + 5 + = 14)
S = 14 - &gt;是(2 + 1 + 2 + 3 + 6 = 14)
S = 14 - &gt;是(2 + 1 + 4 + 5 + 2 + = 14)
S = 14 - &gt;是(2 + 1 + 3 + 2 + 6 = 14)
S = 14 - &gt;是(2 + 1 + 5 + 6 = 14)
S = 14 - &gt;是(2 + 2 + 4 + 6 = 14)
S = 14 - &gt;是(2 + 2 + 3 + 5 + 2 + = 14)
S = 14 - &gt;是(2 + 4 + 3 + 5 + = 14)
S = 14 - &gt;是(2 + 4 + 2 + 6 = 14)
S = 14 - &gt;是(1 + 2 + 4 + 5 + 2 + = 14)
S = 14 - &gt;是(1 + 2 + 3 + 2 + 6 = 14)
S = 14 - &gt;是(1 + 2 + 5 + 6 = 14)
S = 14 - &gt;是(1 + 4 + 3 + 6 = 14)
S = 14 - &gt;是(1 + 5 + 2 + 6 = 14)
S = 14 - &gt;是(2 + 4 + 3 + 5 + = 14)
S = 14 - &gt;是(2 + 4 + 2 + 6 = 14)
S = 14 - &gt;是(4 + 3 + 5 + 2 + = 14)
S = 14 - &gt;是(3 + 5 + 6 = 14)