Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/284.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何使用linq lambda语法查找精确长度的子集_C#_Linq_Set - Fatal编程技术网

C# 如何使用linq lambda语法查找精确长度的子集

C# 如何使用linq lambda语法查找精确长度的子集,c#,linq,set,C#,Linq,Set,可能重复: 假设我输入了范围[1,8] {1,2,3,4,5,6,7,8} 我想找到子集[%,{2}](精确长度为2的所有子集) 尝试: var values = Enumerable.Range(1, 8); var result = from v in values from v2 in values.Skip(v) select new[] { v, v2 }; 但我的眼睛看不清楚 请注意,与其他方法相比,这种方法的效率稍低,因为它

可能重复:

假设我输入了
范围[1,8]

{1,2,3,4,5,6,7,8}
我想找到
子集[%,{2}]
(精确长度为2的所有子集)

尝试:

var values = Enumerable.Range(1, 8);
var result = from v in values
             from v2 in values.Skip(v)
             select new[] { v, v2 };
但我的眼睛看不清楚

请注意,与其他方法相比,这种方法的效率稍低,因为它首先获得所有可能的组合,然后减少不需要的组合。然而,这是一个简单的一行

但我的眼睛看不清楚


请注意,与其他方法相比,这种方法的效率稍低,因为它首先获得所有可能的组合,然后减少不需要的组合。不过,这是一个简单的单行程序。

这里有一个函数,用于查找指定大小的输入序列的所有组合:

public static IEnumerable<IEnumerable<T>> Combinations<T>(this IEnumerable<T> source, int n)
{
    if (n == 0)
        yield return Enumerable.Empty<T>();


    int count = 1;
    foreach (T item in source)
    {
        foreach (var innerSequence in source.Skip(count).Combinations(n - 1))
        {
            yield return new T[] { item }.Concat(innerSequence);
        }
        count++;
    }
}

以下是查找指定大小的输入序列的所有组合的函数:

public static IEnumerable<IEnumerable<T>> Combinations<T>(this IEnumerable<T> source, int n)
{
    if (n == 0)
        yield return Enumerable.Empty<T>();


    int count = 1;
    foreach (T item in source)
    {
        foreach (var innerSequence in source.Skip(count).Combinations(n - 1))
        {
            yield return new T[] { item }.Concat(innerSequence);
        }
        count++;
    }
}


你查过MoreLINQ和EvenMoreLINQ了吗?LINQ和Lambda不一定是一回事。您可以非常轻松地构建一个扩展方法,该方法采用lambda表达式(尽管在本例中,表达式是什么样子?需要更多信息),然后使用递归函数体进行子集计算。Joel Etherton>我可以使用
“Subsets[“+list+”,{2}]”调用Mathematica
。你的尝试给了我你想要的确切结果。有什么问题吗?@user1793607 OP将这些组合显示为他想要的输出,而不是排列。查看维基百科了解差异。你查过MoreLINQ和EvenMoreLINQ吗?LINQ和Lambda不一定是一回事。您可以非常轻松地构建一个扩展方法,该方法采用lambda表达式(尽管在本例中,表达式是什么样子?需要更多信息),然后使用递归函数体进行子集计算。Joel Etherton>我可以使用
“Subsets[“+list+”,{2}]”调用Mathematica
。你的尝试给了我你想要的确切结果。有什么问题吗?@user1793607 OP将这些组合显示为他想要的输出,而不是排列。请参阅wikipedia了解差异。不过这有点粗糙,因为它不适用于任何其他输入大小或设置大小。如果需要,可以进行扩展。这回答了所问的特定问题。实际上,将其从结果集中的固定项目数扩展到动态结果集大小并非易事。不过,这有点不方便,因为它不适用于任何其他输入大小或集大小。如果需要,可以肯定地进行扩展。这回答了所问的具体问题。实际上,将其从结果集中的固定项目数扩展到动态结果集大小并非易事。您可以通过一个简单的
SelectMany
调用来获得交叉连接,而麻烦要小得多。@Servy我不知道这一点。将更新我的答案。Thanks@Servy我不明白SelectMany是否就是这么做的。你能编辑我的答案并将其作为答案发布吗?按要求编辑。还要注意的是,从效率的角度来看,像其他帖子一样生成所需的内容可能比生成所有排列并进行精简要好。@Servy是的,我注意到了。你可以通过一个简单的
SelectMany
调用来获得交叉连接,而麻烦要小得多。@Servy我不知道这一点。将更新我的答案。Thanks@Servy我不明白SelectMany是否就是这么做的。你能编辑我的答案并将其作为答案发布吗?按要求编辑。还要注意的是,从效率的角度来看,像其他帖子一样,只生成您需要的内容可能比生成所有排列并进行精简要好。@Servy是的,我注意到了。这是一个多么棒的片段啊。然而,我花了一点时间才发现它缺少了一个
公共静态类扩展方法
包装器。@Servy您进行过性能测试吗?你的方法比其他两种方法慢30倍左右!我不知道为什么会这样。@nawfal这不会让我感到惊讶。此方法涵盖了一般情况,其他方法硬编码了许多细节,特别是结果集的大小。使其不固定会增加代码的复杂性,并抑制许多优化。这就是说,一般情况下有一些更有效的实现,但它们在概念上也更难理解。最后,请注意,即使在最好的情况下,组合的扩展性也非常糟糕,因此无论实现的质量如何,您都无法将其用于大型数据集。这是一个多么棒的片段啊。然而,我花了一点时间才发现它缺少了一个
公共静态类扩展方法
包装器。@Servy您进行过性能测试吗?你的方法比其他两种方法慢30倍左右!我不知道为什么会这样。@nawfal这不会让我感到惊讶。此方法涵盖了一般情况,其他方法硬编码了许多细节,特别是结果集的大小。使其不固定会增加代码的复杂性,并抑制许多优化。这就是说,一般情况下有一些更有效的实现,但它们在概念上也更难理解。最后,请注意,即使在最好的情况下,组合的扩展性也非常糟糕,因此无论实现的质量如何,您都无法将其用于大型数据集。
var lst = Enumerable.Range(1, 8);
var result = lst.Join(lst, c => 1, c => 1, (i, j) => new[] { i, j })
        .Where(c => c[0] < c[1]);
var result = lst.SelectMany(_ => lst, (i, j) => new[] { i, j })
        .Where(c => c[0] < c[1]);
public static IEnumerable<IEnumerable<T>> Combinations<T>(this IEnumerable<T> source, int n)
{
    if (n == 0)
        yield return Enumerable.Empty<T>();


    int count = 1;
    foreach (T item in source)
    {
        foreach (var innerSequence in source.Skip(count).Combinations(n - 1))
        {
            yield return new T[] { item }.Concat(innerSequence);
        }
        count++;
    }
}
var result = Enumerable.Range(1, 8).Combinations(2);