让,
一个长度为N
int[] iArrN=new int[N]{n1,n2,n3....nN};
//where 1000>N>0 and n1,n2..nN>0(positive integer)
我想从数组中取出M元素。
int[] iArrM=new int[M]{m1,m2...mM};
//where N>M>0 and m1,m2..mM>0(positive integer)
条件 iArraM
中的数字总和必须可以被N
整除
此处示例:
int[] iArrN=new int[5]{1,2,3,4,5};
N=5
M=3;
然后我可以得到
iArrN[1]=2+ iArr[2]=3+ iArr[4]=5=>10%5(N)
int[] iArrM=new int[3]{2,3,5};
要记住: N
和M
可以是任意数字,因此我们需要找出N和M的所有可能值的逻辑算法。
到目前为止我尝试了什么: 我从这个例子开始。
int[] i=new int[5]{1,2,3,4,5};
我正考虑在此数组中使用M
元素进行所有可能的组合(iArrN
)
e.g:
M=3
i[0],i[1],i[2]==1,2,3
i[0],i[1],i[3]==1,2,4
i[0],i[1],i[4]==1,2,5
i[0],i[2],i[3]==1,3,4
i[0],i[2],i[4]==1,3,5
i[0],i[3],i[4]==1,4,5
..
..
..
and so on.
在收到此消息后,我们可以sum(of the combination)
检查divisibility
和N
。
如何使用循环或其他方式获得此组合。 如果您有任何简单合适的解决方案,请告诉我。
答案 0 :(得分:0)
这样做最简单的方法(正如juharr在评论中所提到的)是简单地生成输入集的所有可能子集并过滤以找到满足要求的子集。
生成给定集合X的所有子集是一个相当简单的递归算法:
以下是完整实施:
class Program
{
static void Main(string[] args)
{
var input = new[] { 1, 2, 3, 4 };
var result = GenerateSubsets(input)
.Where(s => s.Sum() % input.Length == 0)
.ToArray(); // {1, 3}, {4} and {1, 3, 4};
}
static IEnumerable<ICollection<T>> GenerateSubsets<T>(ICollection<T> set)
{
// Base case
if (set.Count == 0)
{
yield return new T[0];
yield break;
}
// Generate all subsets
var i = set.First();
foreach (var subset in GenerateSubsets(set.Except(new[] { i }).ToArray()))
{
yield return subset;
yield return subset.Concat(new[] { i }).ToArray();
}
}
}
答案 1 :(得分:0)
遍历数组并散列iArrN[i] mod M, i=0 to (N-1)
的计数/索引。
然后仅生成与哈希的键的总和为N
或零的组合。生成这些组合的递归(或堆叠递归)可以从许多组合中提前退出,从而减少遍历的线程数。
如果值N
或零是iArrN
中的元素,请不要在组合递归中使用它们;相反,稍后添加它们,因为我们知道可以在不影响可分性的情况下添加任何其他组合。
例如:
iArrN = {1,2,3,4,5}
hash = {1:0, 2:1, 3:2, 4:3, 0:4}; (hash_key = iArrN[hash_value] mod N)
combinations: 1 + 2 + 3, too large ... exit
1 + 3 + 4, too large ... exit
1 + 4 works!
exit 1
2 + 3 works!
2 + 4, too large ... exit
exit 2
3 + 4, too large
exit recursion