按顺序生成数字
在给定startIndex,数字数和最大数量的情况下,如何使用LinQ在此序列中生成数字。例如:
Sample Numbers = 1,2,3,4 StartIndex = 1 (ie it should start from 1) Sequence number count = 3 Maximum number = 4 (ie till 4) Expected result given the above details : 1,2,3 1,3,4 1,2,4
有没有办法用linQ做到这一点?
如果您不需要序列的长度是动态的,那么您可以使用:
var startindex=1; var maxindex=4; var data = Enumerable.Range(startindex,maxindex); var qry = from x in data where x == startindex from y in data where x < y from z in data where y < z select new { x, y, z }; foreach (var tuple in qry) { Console.WriteLine("{0} {1} {2}", tuple.x, tuple.y, tuple.z); }
序列长度硬编码为3,因为有3个可枚举的连接:x,y,z。
如果您想动态加入任意数量的枚举,那么您可以使用Eric Lippert的Cartesian Product Linq示例。
您传递一组N个项目的k序列,它将返回一组长度为k的所有组合。
现在,您不希望结果中包含重复的元素。 所以,我在Eric的例子中添加了以下内容:
where accseq.All(accitem => accitem < item)
这是最终的解决方案(为清晰起见而编辑):
var startindex=1; var maxindex=7; var count = 3; // Make a set of count-1 sequences, whose values range from startindex+1 to maxindex List> sequences = new List>(); // We only want permutations starting with startindex. So, the first input sequence to be joined should only have the value startindex. List list1 = new List (); list1.Add(startindex); sequences.Add(list1); // The rest of the input sequences to be joined should contain the range startindex+1 .. maxindex for (int i=1; i< count; i++) { sequences.Add(Enumerable.Range(startindex+1,maxindex-startindex).ToList()); } // Generate the permutations of the input sequences IEnumerable> emptyProduct = new[] { Enumerable.Empty () }; var result = sequences.Aggregate( emptyProduct, (accumulator, sequence) => from accseq in accumulator from item in sequence where accseq.All(accitem => accitem < item) select accseq.Concat(new[] {item})); // Show the result foreach (var x in result) { Console.WriteLine(x); }
试试这个function。
public static IEnumerable> Permute(IEnumerable list) { if (list.Count() == 1) return new List> { list }; return list.Select((a, i1) => Permute(list.Where((b, i2) => i2 != i1)).Select(b => (new List { a }).Union(b))) .SelectMany(c => c); }
//这里范围(startindex,count)
List list1 = Enumerable.Range(1, 3).ToList();
//生成所有排列
var permutationlist = Permute(list1);
好的,首先让我们清楚地说明问题。 我假设你的数字是int
但这是一个几乎无关紧要的细节,但具体性使思考更加流畅
你有一个int
的序列a_0, a_1, a_2, ..., a_N
。
你有一个满足1 <= k <= N + 1
的整数k
。
您有一个起始索引start >=0
和一个结束索引end <= N
您希望所有子序列a_i0, a_i1, a_i2, ..., a_ik
的长度为k
,使得i0 = start
且ik = end
。
那你的算法很简单。 你想要生成{ start + 1, ..., end - 1 }
的大小为k - 2
的所有组合。 给定这样的组合j1, j2, ..., j(k-1)
,对它进行排序,调用得到的有序序列i1, i2, ..., i(k-1)
并返回序列a_start, a_i1, a_i2, ..., a_i(k-1), a_end
。
既然您已经知道问题的正式陈述,以及您需要解决的问题,那么生成所述组合的资源比比皆是。 比照 Google搜索:生成C#或Knuth Volume 4A 组合 。