如何得到所有可能的子集组合?考虑这个ListListdata=newList();data.Add("文本1");data.Add("文本2");data.Add("文本3");data.Add("文本4");我遇到的问题是:如何获取列表子集的每个组合?类似于:#SubsetDimension4Text1;Text2;Text3;Text4#SubsetDimension3Text1;Text2;Text3;文本1;文本2;文本4;文本1;文本3;文本4;文本2;文本3;文本4;#子集维度2Text1;Text2;文本1;文本3;文本1;文本4;文本2;文本3;文本2;文本4;#子集维度1Text1;文字2;文字3;文字4;我想出了一个不错的解决方案,值得在这里分享。在我看来,这个问题的答案需要进行一些性能测试。我会试一下。这是一个社区维基,随时更新。voidPerfTest(){varlist=Enumerable.Range(0,21).ToList();vart1=GetDurationInMs(list.SubSets_LB);vart2=GetDurationInMs(list.SubSets_Jodrell2);vart3=GetDurationInMs(()=>list.CalcCombinations(20));Console.WriteLine("{0}n{1}n{2}",t1,t2,t3);}longGetDurationInMs(Func>>fxn){fxn();//即时通讯???变量计数=0;varsw=Stopwatch.StartNew();foreach(varssinfxn()){count=ss.Sum();}返回sw.ElapsedMilliseconds;}OUTPUT:12811604(_Jodrellnot_Jodrell2)6817Jodrell的更新我在发布模式下构建,这是优化的。当我通过VisualStudio运行时,我没有在1或2之间得到一致的偏差,但在反复运行后,LB的答案获胜,我得到了接近11901260之类的东西但是如果我从命令行运行测试工具,而不是运行通过VisualStudio,我得到的结果更像这样987879更类似于Abaco的回答,不同的实现...foreach(varssindata.SubSets_LB()){);}publicstaticclassSO_EXTENSIONS{publicstaticIEnumerable>SubSets_LB(thisIEnumerableenumerable){Listlist=enumerable.ToList();ulongupper=(ulong)1l=newList(list.Count);for(intj=0;j=upper)break;如果(((i>>j)&1)==1){l.添加(列表[j]);}}yieldreturnl;}}}编辑我接受了性能挑战,这是我的合并,它获得了最佳答案。它似乎在我的测试中表现最好。publicstaticIEnumerable>SubSets_Jodrell2(这个IEnumerable来源){varlist=source.ToList();varlimit=(ulong)(10;i--){yieldreturnlist.SubSet(i);}}privatestaticIEnumerableSubSet(thisIListsource,ulongbits){for(vari=0;i>i)&1)==1){yieldreturnsource[i];相同的想法,几乎与LB的回答相同,但我自己的解释。我避免使用内部List和Math.Pow。publicstaticIEnumerable>SubSets_Jodrell(这个IEnumerable源){varcount=source.Count();if(count>64){thrownewOverflowException("不支持...");}varlimit=(ulong)(10;i--){yieldreturnsource.SubSet(i);}}privatestaticIEnumerableSubSet(这个IEnumerable源,ulong位){varcheck=(ulong)1;foreach(vartinsource){if((bits&check)>0){yieldreturnt;}check你会注意到这些方法不能处理初始集合中超过64个元素,但无论如何它都需要一段时间才能开始。我为列表开发了一个简单的扩展方法://////获取列表中元素的所有组合//////子集维度///包含所有不同子集的IEnumerablepublicstaticIEnumerable>CalcCombinations(thisListlist,intsubsetDimension){//首先我们将创建一个二进制矩阵。单个行的维度//必须是我们正在处理的列表的维度//(我们需要为每个元素添加0或1)所以行//维度是为了获得行长度=list.count我们必须//用前2^list.Count二进制数填充矩阵introwDimension=Convert.ToInt32(Math.Pow(2,list.Count));//现在我们开始数数!我们将用从1//(0无意义)到rowDimension的每个数字填充我们的矩阵//我们正在创建二进制掩码,因此名称为ListcombinationMasks=newList();对于(inti=1;ix=='0'?0:1).Reverse().ToArray().CopyTo(mask,0);//为什么我们要保留一个维度的掩码不是子集之一吗?//然后我们必须过滤它!如果(mask.Sum()==subsetDimension)combinationMasks.Add(mask);}//现在我们将矩阵应用于我们的列表foreach(int[]maskincombinationMasks){//以相反的顺序执行循环以避免索引越界for(intiter=mask.Length-1;iter>=0;iter--){//每当找到0时,相应的项目就会从列表中删除如果(mask[iter]==0)temporaryList.RemoveAt(iter);}yieldreturntemporaryList;所以考虑问题中的例子:#RowDimensionof4(list.Count)BinaryNumbersto2^4#BinaryMatrix0001=>skip0010=>skip[...]0111=>添加//文本2;文本3;Text4[...]1011=>添加//Text1;Text3;Text41100=>跳过1101=>添加//Text1;Text2;Text41110=>添加//Text1;Text2;Text31111=>skip希望这对某人有帮助:)如果您需要说明或想要贡献,请随时添加答案或评论(以更合适的为准)以上就是C#学习教程:如何获取所有可能的子集组合?如果所有分享的内容对你有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处:
