3

使用下面的列表,如何在不进行完整的蛮力比较的情况下从下面的列表中获取不同的列表?在示例中,list2 和 list3 是相同的,所以我只想要 list1 和 list2。

var list1 = new List<int>{1,2,3,4,5};
var list2 = new List<int>{2,3};
var list3 = new List<int>{3,2};
4

3 回答 3

3

将列表替换为HashSets 的集合。

然后你可以写

hashSets.Distinct(HashSet<int>.CreateSetComparer())
于 2013-06-25T18:40:04.163 回答
0

编辑使用 List<>.Sort + IEnumerable 的 .Any 和 .SequenceEqual

public static List<List<int>> Test1(List<int>[] lists)
{
    var result = new List<List<int>>();
    foreach(var list in lists)
    {
        list.Sort();
        if(!result.Any(elm => elm.SequenceEqual(list)))
            result.Add(list);
    }
    return result;
}

这是一个简单的基准测试/测试,显示了 HashSet 方法和 pre-.Sort .Any .SequenceEqual 方法。编辑 http://ideone.com/x3CJ8I当然 ideone 可能不是最好的基准测试平台,所以请随意在您自己的机器上运行它。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Diagnostics;

public class Demo
{
    public static void Main()
    {
        int tries = 100;
        int count = 50;
        int size = 1000;
        Random rnd = new Random();
        List<int>[] list;
        Stopwatch sw;

        sw = new Stopwatch();
        for(int x=0; x<tries; x++)
        {
            list = new List<int>[count];
            for(int y=0; y<count; y++)
            {
                list[y] = new List<int>();
                for(int z=0; z<size; z++)
                {
                    int n = rnd.Next();
                    list[y].Add(n);
                }
                if((y % 5) == 0 && y > 0)
                { // make repeated lists for the uniqueness check
                    list[y-1] = new List<int>(list[y]);
                    list[y-1].Reverse();
                }
            }
            sw.Start();
            Test1(list);
            sw.Stop();
        }
        Console.WriteLine( sw.Elapsed.ToString() );

        sw = new Stopwatch();
        for(int x=0; x<tries; x++)
        {
            list = new List<int>[count];
            for(int y=0; y<count; y++)
            {
                list[y] = new List<int>();
                for(int z=0; z<size; z++)
                {
                    int n = rnd.Next();
                    list[y].Add(n);
                }
                if((y % 5) == 0 && y > 0)
                { // make repeated lists for the uniqueness check
                    list[y-1] = new List<int>(list[y]);
                    list[y-1].Reverse();
                }
            }
            sw.Start();
            Test2(list);
            sw.Stop();
        }
        Console.WriteLine( sw.Elapsed.ToString() );
    }
    public static List<List<int>> Test1(List<int>[] lists)
    {
        var result = new List<List<int>>();
        foreach(var list in lists)
        {
            list.Sort();
            if(!result.Any(elm => elm.SequenceEqual(list)))
                result.Add(list);
        }
        return result;
    }
    public static List<HashSet<int>> Test2(List<int>[] lists)
    {
        var result = new List<HashSet<int>>();
        foreach(var list in lists)
        {
            result.Add(new HashSet<int>(list));
        }
        result = result.Distinct(HashSet<int>.CreateSetComparer()).ToList();
        return result;
    }
}

编辑我有时间修改测试,结果发现创建 HashSets + .Distinct 的开销与 .Sort + .Any + .SequenceEqual 的编辑非常相似。http://ideone.com/x3CJ8I

于 2013-06-25T19:10:59.090 回答
-1

您也可以连接三个列表,然后执行 .Distinct()

list<int> newList = list1.Concat(list2.Concat(list3)).Distinct();
于 2013-06-25T19:20:01.593 回答