两个List 合并?

时间:2022-04-17 20:47:25
我想合并2个List<string>,而且要求去除重复的项


            List<string> str1 = new List<string>();
            List<string> str2 = new List<string>();
            str1.Add("FUCK");
            str1.Add("lb");
            str1.Add("sorr");
            str2.Add("FUCK");
            str2.Add("12");

            str1.AddRange(str2);


AddRange用来合并List<string>是没什么问题,问题是不能除去重复的项,后来我这样


            List<string> str1 = new List<string>();
            List<string> str2 = new List<string>();
            str1.Add("FUCK");
            str1.Add("lb");
            str1.Add("sorr");
            str2.Add("FUCK");
            str2.Add("12");

            for (int i = 0; i < str2.Count; i++)
                if (!str1.Contains(str2[i]))
                    str1.Add(str2[i]);



这样是没问题了。这样做会不会效率低下呢?将来我的一个List<string>里面可能就是几十W个元素啊!

各位认为两个List<string>的去重合并有什么好的方法?我要求是效率一定要高!

30 个解决方案

#1


你让元素少的list做for循环效率可能会提高.

#2


那还不直接用一个...up下

#3


要不?二叉树的东西考虑下?

#4


直接用 LINQ 的 union 方法吧,去重的。


using System.linq;


然后你用

str1.Union(str2);

#5


几十W个只要不是对性能很苛刻的地方,基本上没什么问题啊

#6


方法无非是循环和用Linq,因为没有大数据,所以不能做性能测试。既然你有大数据,建议自己比较下性能就知道哪种好了。
我猜测用foreach循环效率应该是最高的,for 其次,而用Linq应该是效率最低的。看似Linq简单,其实内部实现非常复杂的,这种看不到实现过程的东西,往往是方便了使用而降低了性能,不过还是实践出真理,需要用大数据来比较了才能说明哪个快。

#7


引用 5 楼 windinwing 的回复:
几十W个只要不是对性能很苛刻的地方,基本上没什么问题啊

对性能要求很苛刻。
相当苛刻。

#8


引用 6 楼 qldsrx 的回复:
方法无非是循环和用Linq,因为没有大数据,所以不能做性能测试。既然你有大数据,建议自己比较下性能就知道哪种好了。
我猜测用foreach循环效率应该是最高的,for 其次,而用Linq应该是效率最低的。看似Linq简单,其实内部实现非常复杂的,这种看不到实现过程的东西,往往是方便了使用而降低了性能,不过还是实践出真理,需要用大数据来比较了才能说明哪个快。


Linq的效率低我是知道的。for和foreach不知道如何。

顺便说下:几十万只是保守估计,搞不好是上千万的。

#9


有没有哪位兄台有算法的改进意见?
分可以继续加

#10


你这个循环里面,影响性能的主要是这个if (!str1.Contains(str2[i]))地方。
首先是str2[i],它需要一个寻址过程,如果你用foreach的话,直接地址在List内部依次移动,可以省去了一个寻址的过程;
其次是Contains方法的算法,如果说C#的这个方法不快的话,可以考虑使用C++自己写一个比较的方法来加快速度。毕竟使用C++的指针操作速度才是最快的。

#11


只接AddRange后排序,在做一次循环,每次记录上一轮的元素,和下一个元素,如果一样记录到删除列表
 理论上比每次都check好一点,不过也许更慢,试下

#12


不知道 HashSet 可不可以

#13


foreach效率比for高?

#14


foreach .net编译器做了更多的优化,少了边界检查 .net1.0以上版本foreach性能就很高了

#15


那各位认为如果直接合并后,在str1中去重,用什么算法比较好?

#16


跟排序差不多的原理.冒泡,二分等
差别在于排序是判断大小关系,lz是需要判断是否相等.

另外可以试试用hashtable,散列算法,查找重复应该很快.

linq也可以试试
    var list2 = (from item in list
                    select item).Distinct(); 

另外,难到不是数据库里查询出来的? 这些list哪来的,数据库里的排序去重复是很快的

#17


引用 8 楼 bloodsworder 的回复:
引用 6 楼 qldsrx 的回复:
方法无非是循环和用Linq,因为没有大数据,所以不能做性能测试。既然你有大数据,建议自己比较下性能就知道哪种好了。
我猜测用foreach循环效率应该是最高的,for 其次,而用Linq应该是效率最低的。看似Linq简单,其实内部实现非常复杂的,这种看不到实现过程的东西,往往是方便了使用而降低了性能,不过还是实践出真理,需要用大数据来比较了才能说明哪个快。


Linq的效率低我是知道的。for和foreach不知道如何。

顺便说下:几十万只是保守估计,搞不好是上千万的。

词典啊?存那么多东西
真要是那样就应该考虑存储的位置了
是不是应当首次存储在list里
可以用其他方式去重以后最终存到list内

#18


不是数据库里出来的。

#19


str1.Distinct<string>(); //取不重复值。

#20


Distinct我怎么没有啊?

#21


环境: VS2008


static void Main(string[] args)
        {
            List<string> str1 = new List<string>();
            List<string> str2 = new List<string>();
            str1.Add("FUCK");
            str1.Add("lb");
            str1.Add("sorr");

            str2.Add("FUCK");
            str2.Add("12");

            str1.AddRange(str2);

            foreach (string s in str1.Distinct<string>())
            {
                Console.WriteLine(s);
            }
            ConsoleKeyInfo d = Console.ReadKey(true);
            Console.Write(d);
        }

#22


引用 6 楼 qldsrx 的回复:
方法无非是循环和用Linq,因为没有大数据,所以不能做性能测试。既然你有大数据,建议自己比较下性能就知道哪种好了。
 我猜测用foreach循环效率应该是最高的,for 其次,而用Linq应该是效率最低的。看似Linq简单,其实内部实现非常复杂的,这种看不到实现过程的东西,往往是方便了使用而降低了性能,不过还是实践出真理,需要用大数据来比较了才能说明哪个快。

未必哦,linq用Hash来加速的

#23


用Hash表或Dictionary,List<>这种结构本身就需要遍历来获取数据.效率肯定高不到哪去.
Hash表哪怕再长,获取指定元素的时间始终是一个常量.


var str1= new Dictionary<string,string>();
var str2= new Dictionary<string,string>();

            str1.Add("FUCK",String.Empty);
            str1.Add("lb",String.Empty);
            str1.Add("sorr",String.Empty);
            str2.Add("FUCK",String.Empty);
            str2.Add("12",String.Empty);
foreach(string s in str2.Keys)
{
  if (!str1.ContainsKey(s)) str1.add(s,String.Empty);
}


#24



......
            IEnumerable<string> union = str1.Union(str2);
            foreach (string s in union)
            {
                Console.WriteLine(s);
            }
....

Union: 连接两个序列的不重复值。

#25


引用 23 楼 bwangel 的回复:
用Hash表或Dictionary,List <>这种结构本身就需要遍历来获取数据.效率肯定高不到哪去.
Hash表哪怕再长,获取指定元素的时间始终是一个常量.

C# codevar str1=new Dictionary<string,string>();var str2=new Dictionary<string,string>();

            str1.Add("FUCK",String.Empty);
            str1.Add("lb",String.Empty);
            str1.Add("sorr",String.Empty);
            str2.Add("FUCK",String.Empty);
            str2.Add("12",String.Empty);foreach(string sin str2.Keys)
{if (!str1.ContainsKey(s)) str1.add(s,String.Empty);
}


说的有道理。Hash真的这么好吗?

#26


奇怪,我的str1后面 . 下既没有 Distinct也没有Union?
命令行下也没有Linq?

#27


我也是2008呀

#28


C++  STL 里有个set

不知道C#里有没有类似的东西

#29


21楼的方法没什么实用价值··
你那叫合并?

#30


该回复于2012-07-09 15:00:29被版主删除

#1


你让元素少的list做for循环效率可能会提高.

#2


那还不直接用一个...up下

#3


要不?二叉树的东西考虑下?

#4


直接用 LINQ 的 union 方法吧,去重的。


using System.linq;


然后你用

str1.Union(str2);

#5


几十W个只要不是对性能很苛刻的地方,基本上没什么问题啊

#6


方法无非是循环和用Linq,因为没有大数据,所以不能做性能测试。既然你有大数据,建议自己比较下性能就知道哪种好了。
我猜测用foreach循环效率应该是最高的,for 其次,而用Linq应该是效率最低的。看似Linq简单,其实内部实现非常复杂的,这种看不到实现过程的东西,往往是方便了使用而降低了性能,不过还是实践出真理,需要用大数据来比较了才能说明哪个快。

#7


引用 5 楼 windinwing 的回复:
几十W个只要不是对性能很苛刻的地方,基本上没什么问题啊

对性能要求很苛刻。
相当苛刻。

#8


引用 6 楼 qldsrx 的回复:
方法无非是循环和用Linq,因为没有大数据,所以不能做性能测试。既然你有大数据,建议自己比较下性能就知道哪种好了。
我猜测用foreach循环效率应该是最高的,for 其次,而用Linq应该是效率最低的。看似Linq简单,其实内部实现非常复杂的,这种看不到实现过程的东西,往往是方便了使用而降低了性能,不过还是实践出真理,需要用大数据来比较了才能说明哪个快。


Linq的效率低我是知道的。for和foreach不知道如何。

顺便说下:几十万只是保守估计,搞不好是上千万的。

#9


有没有哪位兄台有算法的改进意见?
分可以继续加

#10


你这个循环里面,影响性能的主要是这个if (!str1.Contains(str2[i]))地方。
首先是str2[i],它需要一个寻址过程,如果你用foreach的话,直接地址在List内部依次移动,可以省去了一个寻址的过程;
其次是Contains方法的算法,如果说C#的这个方法不快的话,可以考虑使用C++自己写一个比较的方法来加快速度。毕竟使用C++的指针操作速度才是最快的。

#11


只接AddRange后排序,在做一次循环,每次记录上一轮的元素,和下一个元素,如果一样记录到删除列表
 理论上比每次都check好一点,不过也许更慢,试下

#12


不知道 HashSet 可不可以

#13


foreach效率比for高?

#14


foreach .net编译器做了更多的优化,少了边界检查 .net1.0以上版本foreach性能就很高了

#15


那各位认为如果直接合并后,在str1中去重,用什么算法比较好?

#16


跟排序差不多的原理.冒泡,二分等
差别在于排序是判断大小关系,lz是需要判断是否相等.

另外可以试试用hashtable,散列算法,查找重复应该很快.

linq也可以试试
    var list2 = (from item in list
                    select item).Distinct(); 

另外,难到不是数据库里查询出来的? 这些list哪来的,数据库里的排序去重复是很快的

#17


引用 8 楼 bloodsworder 的回复:
引用 6 楼 qldsrx 的回复:
方法无非是循环和用Linq,因为没有大数据,所以不能做性能测试。既然你有大数据,建议自己比较下性能就知道哪种好了。
我猜测用foreach循环效率应该是最高的,for 其次,而用Linq应该是效率最低的。看似Linq简单,其实内部实现非常复杂的,这种看不到实现过程的东西,往往是方便了使用而降低了性能,不过还是实践出真理,需要用大数据来比较了才能说明哪个快。


Linq的效率低我是知道的。for和foreach不知道如何。

顺便说下:几十万只是保守估计,搞不好是上千万的。

词典啊?存那么多东西
真要是那样就应该考虑存储的位置了
是不是应当首次存储在list里
可以用其他方式去重以后最终存到list内

#18


不是数据库里出来的。

#19


str1.Distinct<string>(); //取不重复值。

#20


Distinct我怎么没有啊?

#21


环境: VS2008


static void Main(string[] args)
        {
            List<string> str1 = new List<string>();
            List<string> str2 = new List<string>();
            str1.Add("FUCK");
            str1.Add("lb");
            str1.Add("sorr");

            str2.Add("FUCK");
            str2.Add("12");

            str1.AddRange(str2);

            foreach (string s in str1.Distinct<string>())
            {
                Console.WriteLine(s);
            }
            ConsoleKeyInfo d = Console.ReadKey(true);
            Console.Write(d);
        }

#22


引用 6 楼 qldsrx 的回复:
方法无非是循环和用Linq,因为没有大数据,所以不能做性能测试。既然你有大数据,建议自己比较下性能就知道哪种好了。
 我猜测用foreach循环效率应该是最高的,for 其次,而用Linq应该是效率最低的。看似Linq简单,其实内部实现非常复杂的,这种看不到实现过程的东西,往往是方便了使用而降低了性能,不过还是实践出真理,需要用大数据来比较了才能说明哪个快。

未必哦,linq用Hash来加速的

#23


用Hash表或Dictionary,List<>这种结构本身就需要遍历来获取数据.效率肯定高不到哪去.
Hash表哪怕再长,获取指定元素的时间始终是一个常量.


var str1= new Dictionary<string,string>();
var str2= new Dictionary<string,string>();

            str1.Add("FUCK",String.Empty);
            str1.Add("lb",String.Empty);
            str1.Add("sorr",String.Empty);
            str2.Add("FUCK",String.Empty);
            str2.Add("12",String.Empty);
foreach(string s in str2.Keys)
{
  if (!str1.ContainsKey(s)) str1.add(s,String.Empty);
}


#24



......
            IEnumerable<string> union = str1.Union(str2);
            foreach (string s in union)
            {
                Console.WriteLine(s);
            }
....

Union: 连接两个序列的不重复值。

#25


引用 23 楼 bwangel 的回复:
用Hash表或Dictionary,List <>这种结构本身就需要遍历来获取数据.效率肯定高不到哪去.
Hash表哪怕再长,获取指定元素的时间始终是一个常量.

C# codevar str1=new Dictionary<string,string>();var str2=new Dictionary<string,string>();

            str1.Add("FUCK",String.Empty);
            str1.Add("lb",String.Empty);
            str1.Add("sorr",String.Empty);
            str2.Add("FUCK",String.Empty);
            str2.Add("12",String.Empty);foreach(string sin str2.Keys)
{if (!str1.ContainsKey(s)) str1.add(s,String.Empty);
}


说的有道理。Hash真的这么好吗?

#26


奇怪,我的str1后面 . 下既没有 Distinct也没有Union?
命令行下也没有Linq?

#27


我也是2008呀

#28


C++  STL 里有个set

不知道C#里有没有类似的东西

#29


21楼的方法没什么实用价值··
你那叫合并?

#30


该回复于2012-07-09 15:00:29被版主删除