C# 使用特定的算法逻辑从数组中获取数组

C# 使用特定的算法逻辑从数组中获取数组,c#,arrays,algorithm,logic,C#,Arrays,Algorithm,Logic,让,, 长度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

让,, 长度
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)

记住:
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.
得到这个后,我们可以用
N
检查
和(组合的)
可分性

如何使用循环或其他方法获得此组合。
如果您有任何简单且合适的解决方案,请告诉我。

最简单的方法(如juharr在评论中提到的)是简单地生成输入集的所有可能子集,并筛选出满足要求的子集

生成给定集合X的所有子集是一个相当简单的递归算法:

  • 如果X为空,则唯一的子集是空集。结束
  • 否则,从X中删除一些元素i并递归生成结果集X’的所有子集
  • X的子集是X′的子集,以及通过将i附加到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();
            }
        }
    }
    
    类程序
    {
    静态void Main(字符串[]参数)
    {
    变量输入=新[]{1,2,3,4};
    var结果=生成子集(输入)
    .Where(s=>s.Sum()%input.Length==0)
    .ToArray();/{1,3},{4}和{1,3,4};
    }
    静态IEnumerable生成子集(ICollection set)
    {
    //基本情况
    如果(set.Count==0)
    {
    收益率-收益率新T[0];
    屈服断裂;
    }
    //生成所有子集
    var i=set.First();
    foreach(GenerateSubsets(set.Except(new[]{i}).ToArray()中的var子集)
    {
    收益子集;
    产生返回子集.Concat(new[]{i}).ToArray();
    }
    }
    }
    
    遍历数组并散列
    iArrN[i]mod M,i=0到(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
    

    如果你在寻找算法,那么可能不是最好的地方——至少要弄清楚什么是“合适的”解决方案(大多数这样的问题都有很高的O(…)复杂性——所以回答的人需要知道你的边界)。。。如果您只需要代码-抓住任何“所有组合”问题,只需检查所需条件的总和。Eric Lippert有一个公式,介绍如何获得给定集合中给定长度的所有组合。谢谢@juharr,让我检查一下。:)@juharr我认为这篇文章没有任何关于确保所选组合的总和为可被数组长度整除的数字的内容。@AsadSaeeduddin没有,但这是最简单的部分。使用Eric的代码,您需要做的就是
    iArrN.combines(M).Where(c=>c.Sum()%N==0)
    获取满足条件的所有组合,或者将
    Where
    交换为
    FirstOrDefault
    (如果您只需要一个)。
    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