按顺序生成数字

发布于 2024-11-03 04:18:56 字数 299 浏览 0 评论 0原文

给定 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 来实现?

How can i generate numbers using LinQ in this sequence given the startIndex,count of numbers and the maximum number.For example:

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

Is there a way to do it using linQ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

人事已非 2024-11-10 04:18:56

如果您不需要序列的长度是动态的,那么您可以使用:

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 的笛卡尔积 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<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);
}

If you didn't need the length of you sequences to be dynamic, then you could use:

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);
}

The sequence length is hardcoded to 3, because there are 3 enumerables being joined: x, y, z.

If you want to dynamically join an arbitrary number of enumerables, then you can use Eric Lippert's Cartesian Product Linq example.

You pass a set of k sequences of N items, and it will return a set of all combinations of length k.

Now, you don't want repeated elements in your results.
So, I added the following to Eric's example:

where accseq.All(accitem => accitem < item)

Here's the final solution (edited for clarity):

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);
}
挖个坑埋了你 2024-11-10 04:18:56

试试这个功能。

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);
        }

//这里 Range(startindex, count)

List<int> list1 = Enumerable.Range(1, 3).ToList();

//生成所有排列

var permutationlist = Permute(list1);

在此处输入图像描述

Try this function.

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);
        }

//Here Range(startindex, count)

List<int> list1 = Enumerable.Range(1, 3).ToList();

//generates all permutations

var permutationlist = Permute(list1);

enter image description here

红衣飘飘貌似仙 2024-11-10 04:18:56

好吧,首先我们把问题说清楚。我假设你的数字是int,但这基本上是一个无关紧要的细节,但具体性让思考变得更加简单。

你有一个序列a_0, a_1, a_2, ..., a_Nint 的 >。

您有一个满足 1 <= k <= N + 1 的整数 k

您有一个起始索引 start >=0 和一个结束索引 end <= N

您希望长度为 k 的所有子序列 a_i0, a_i1, a_i2, ..., a_ik 使得 i0 = startik =结束

那么你的算法就很简单了。您想要生成 { 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# 高德纳第 4A 卷

Okay, first let's state the problem clearly. I'll assume your numbers are int but that's a mostly irrelevant detail but the concreteness makes thinking go more smo

You have a sequence a_0, a_1, a_2, ..., a_N of int.

You have an integer k satisfying 1 <= k <= N + 1.

You have a starting index start >=0 and an ending index end <= N.

You want all subsequences a_i0, a_i1, a_i2, ..., a_ik of length k such that i0 = start and ik = end.

Then your algorithm is simple. You want to produce all combinations of size k - 2 of { start + 1, ..., end - 1 }. Given such a combination j1, j2, ..., j(k-1), order it, call the resulting ordered sequence i1, i2, ..., i(k-1) and return the sequence a_start, a_i1, a_i2, ..., a_i(k-1), a_end.

Now that you know a formal statement of the problem, and what you need to solve it, resources abound for generating said combinations. cf. Google search : Generating combinations C# or Knuth Volume 4A.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文