微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

c# – 序列序列的2组合的交集的并集

如何在序列序列中找到2个或更多序列中出现的项集?

换句话说,我希望在传递的序列中至少有2个出现不同的值.

注意:
这不是所有序列的交叉,而是所有序列对的交叉的并集.

笔记2:
包括序列与自身的对或2组合.那太傻了.

我自己做了一个尝试,

public static IEnumerable<T> UnionOfIntersects<T>(
                                  this IEnumerable<IEnumerable<T>> source)
{
    var pairs =
            from s1 in source
            from s2 in source
            select new { s1,s2 };

    var intersects = pairs
        .Where(p => p.s1 != p.s2)
        .Select(p => p.s1.Intersect(p.s2));

    return intersects.SelectMany(i => i).distinct();
}

但是我担心这可能是次优的,我认为它包括A,B和B对的交叉点,A似乎效率低下.我也认为可能有一种更有效的方法来复合集合,因为它们是迭代的.

我在下面包含一些示例输入和输出

{ { 1,1,2,3,4,5,7 },{ 5,6,{ 2,7,9 },{ 4 } }

回报

{ 2,7 }

{ { 1,3} } or { {} } or { }

回报

{ }

我正在寻找可读性和潜在性能的最佳组合.

编辑

我已经对当前答案进行了一些初步测试,my code is here.输出如下.

Original valid:True
DoomerOneLine valid:True
DoomersqlLike valid:True
Svinja valid:True
Adricadar valid:True
Schmelter valid:True
Original 100000 iterations in 82ms
DoomerOneLine 100000 iterations in 58ms
DoomersqlLike 100000 iterations in 82ms
Svinja 100000 iterations in 1039ms
Adricadar 100000 iterations in 879ms
Schmelter 100000 iterations in 9ms

目前,看起来Tim Schmelter’s answer的表现至少要好一个数量级.

解决方法

您可以尝试这种方法,它可能更有效,并且还允许指定最小交叉计数和使用的比较器:
public static IEnumerable<T> UnionOfIntersects<T>(this IEnumerable<IEnumerable<T>> source,int minIntersectionCount,IEqualityComparer<T> comparer = null)
{
    if (comparer == null) comparer = EqualityComparer<T>.Default;
    foreach (T item in source.SelectMany(s => s).distinct(comparer))
    {
        int containedInHowManySequences = 0;
        foreach (IEnumerable<T> seq in source)
        {
            bool contained = seq.Contains(item,comparer);
            if (contained) containedInHowManySequences++;
            if (containedInHowManySequences == minIntersectionCount)
            {
                yield return item;
                break;
            }
        }
    }
}

一些解释词:

>它枚举所有序列中的所有唯一项.由于distinct正在使用一个集合,这应该非常有效.如果所有序列中有许多重复,这可以帮助加快速度.>如果包含唯一项,内循环只会查看每个序列.之前它使用Enumerable.Contains,一旦找到一个项目就停止执行(所以重复没有问题).>如果交叉点计数达到最小交叉点计数,则会生成此项目并检查下一个(唯一)项目.

原文地址:https://www.jb51.cc/csharp/244836.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐