如果给定startIndex,数字数和最大数,我如何使用LinQ在此序列中生成数字。例如:
Sample Numbers = 1,2,3,4
StartIndex = 1 (i.e it should start from 1)
Sequence number count = 3
Maximum number = 4 (i.e till 4)
Expected result given the above details :
1,2,3
1,3,4
1,2,4
有没有办法用linQ做到?
答案 0 :(得分:2)
如果您不需要序列的长度是动态的,那么您可以使用:
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's Cartesian Product Linq example.
你传递了一组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<List<int>> sequences = new List<List<int>>();
// We only want permutations starting with startindex. So, the first input sequence to be joined should only have the value startindex.
List<int> list1 = new List<int>();
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<IEnumerable<int>> emptyProduct = new[] { Enumerable.Empty<int>() };
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);
}
答案 1 :(得分:0)
尝试此功能。
public static IEnumerable<IEnumerable<T>> Permute<T>(IEnumerable<T> list)
{
if (list.Count() == 1)
return new List<IEnumerable<T>> { list };
return list.Select((a, i1) => Permute(list.Where((b, i2) => i2 != i1)).Select(b => (new List<T> { a }).Union(b)))
.SelectMany(c => c);
}
//这里范围(startindex,count)
List<int> list1 = Enumerable.Range(1, 3).ToList();
//生成所有排列
var permutationlist = Permute(list1);
答案 2 :(得分:0)
好的,首先让我们清楚地说明问题。我假设你的数字是int
,但这是一个大多数不相关的细节,但具体性让思考变得更加白痴
您的序列a_0, a_1, a_2, ..., a_N
为int
。
您有一个满足k
的整数1 <= k <= N + 1
。
您有一个起始索引start >=0
和一个结束索引end <= N
。
您希望所有a_i0, a_i1, a_i2, ..., a_ik
长度为k
的子序列i0 = start
和ik = end
。
然后你的算法很简单。您希望生成k - 2
的{{1}}大小的所有组合。给定这样的组合{ start + 1, ..., end - 1 }
,对其进行排序,调用生成的有序序列j1, j2, ..., j(k-1)
并返回序列i1, i2, ..., i(k-1)
。
现在你已经知道问题的正式陈述,以及你需要解决的问题,生成所述组合的资源比比皆是。比照Google search : Generating combinations C#或Knuth Volume 4A。