C#两个数组的相似性

Joc*_*cie 5 c# arrays

必须是一个更好的办法来做到这一点,我敢肯定...

// Simplified code
var a = new List<int>() { 1, 2, 3, 4, 5, 6 };
var b = new List<int>() { 2, 3, 5, 7, 11 };
var z = new List<int>();
for (int i = 0; i < a.Count; i++)
    if (b.Contains(a[i]))
        z.Add(a[i]);
// (z) contains all of the numbers that are in BOTH (a) and (b), i.e. { 2, 3, 5 }
Run Code Online (Sandbox Code Playgroud)

我不介意使用上述技术,但我想要快速有效的东西(我需要多次比较非常大的列表<>),这似乎都不是!有什么想法吗?

编辑:因为它有所不同 - 我使用的是.NET 4.0,初始数组已经排序并且不包含重复项.

dic*_*ice 6

您可以使用IEnumerable.Intersect.

var z = a.Intersect(b);
Run Code Online (Sandbox Code Playgroud)

可能比您当前的解决方案更有效.

请注意,您遗漏了一条重要的信息 - 列表是否正在订购.如果它们是几个嵌套的循环,它们恰好通过每个输入数组一次,每个输入数组可能更快 - 写起来更有趣.

编辑 回复您对订购的评论:

在循环第一个尝试-这需要代表您稍加调整,但是否适合你的初始数据.

    int j = 0;
    foreach (var i in a)
    {
        int x = b[j];
        while (x < i)
        {
            if (x == i)
            {
                z.Add(b[j]);
            }
            j++;
            x = b[j];
        }
    }
Run Code Online (Sandbox Code Playgroud)

这是你需要添加一些单元测试的地方;)

编辑 最后一点 - 很可能Linq可以使用SortedList非常有效地执行此交集,如果性能是一个问题,则值得测试各种解决方案.如果您以无序方式加载数据,请不要忘记将排序考虑在内.

一个最终编辑,因为有一些来回此和人们可能正在使用上面没有正确调试它我在这里发布一个更高版本:

        int j = 0;
        int b1 = b[j];
        foreach (var a1 in a)
        {
            while (b1 <= a1)
            {
                if (b1 == a1)
                    z1.Add(b[j]);
                j++;
                if (j >= b.Count)
                    break;
                b1 = b[j];
            }
        }
Run Code Online (Sandbox Code Playgroud)