C#两路list数组归并去重

个相同类型已排序数据进行合并,虽然list数组中有AddRange方法,但它只是把第二个数组从第一个数组末尾插入,假如两个数组有重复数据,保存进去。
还有Union方法合并去重,首先会从第一个数组进行检查然后再把第二个数组数据从第一个数组依次从末尾插入,但相对于自定义类型排序还是不能有效解决问题。

归并排序是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。

归并过程为:比较a[i]和a[j]的大小,若a[i]≤a[j],则将第一个有序表中的元素a[i]复制到r[k]中,并令i和k分别加上1;否则将第二个有序表中的元素a[j]复制到r[k]中,并令j和k分别加上1,如此循环下去,直到其中一个有序表取完,然后再将另一个有序表中剩余的元素复制到r中从下标k到下标t的单元。归并排序的算法我们通常用递归实现,先把待排序区间[s,t]以中点二分,接着把左边子区间排序,再把右边子区间排序,最后把左区间和右区间用一次归并操作合并成有序的区间[s,t]。

Examples

 1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4
5 namespace Examples.Utils
6 {
7 public static class CollectionUtils
8 {
9 public static IList<T> MergeSortedLists<T>(Comparison<T> comparision, IList<T> list1, IList<T> list2)
10 {
11 var mergedList = new List<T>(list1.Count + list2.Count);
12 int i = 0, j = 0;
13 while (i < list1.Count && j < list2.Count)
14 {
15 var result = comparision(list1[i], list2[j]);
16 if (result <= 0)
17 {
18 if (result == 0)
19 {
20 j++;
21 }
22 mergedList.Add(list1[i++]);
23 }
24 else
25 {
26 mergedList.Add(list2[j++]);
27 }
28 }
29 while (i < list1.Count)
30 {
31 mergedList.Add(list1[i++]);
32 }
33 while (j < list2.Count)
34 {
35 mergedList.Add(list2[j++]);
36 }
37 return mergedList;
38 }
39 }
40 }

TestExamples

 1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using NUnit.Framework;
5
6 namespace Examples.Utils.Tests
7 {
8 [TestFixture]
9 public class CollectionUtilsTests
10 {
11 [Test]
12 public void Merge2TestNoDuplicate()
13 {
14 var list1 = new List<int> {100, 50, 20, 10, 1};
15 var list2 = new List<int> {500, 70, 30, 15, 5};
16 var mergedList = CollectionUtils.MergeSortedLists(IntegerComparision, list1, list2);
17 var expectedList = GetExpectedMergedList(IntegerComparision, list1, list2);
18 Assert.AreEqual(expectedList.Count, mergedList.Count);
19 CollectionAssert.AreEqual(expectedList, mergedList);
20 }
21
22 [Test]
23 public void Merge2TestWithDuplicates()
24 {
25 var list1 = new List<int> {100, 50, 20, 10, 1};
26 var list2 = new List<int> {500, 70, 50, 15, 1};
27 var mergedList = CollectionUtils.MergeSortedLists(IntegerComparision, list1, list2);
28 var expectedList = GetExpectedMergedList(IntegerComparision, list1, list2);
29 Assert.AreEqual(expectedList.Count, mergedList.Count);
30 CollectionAssert.AreEqual(expectedList, mergedList);
31 }
32
33 [Test]
34 public void Merge2TestNoOverlap1()
35 {
36 var list1 = new List<int> {500, 300, 250, 150, 120};
37 var list2 = new List<int> {100, 50, 20, 10, 1};
38 var mergedList = CollectionUtils.MergeSortedLists(IntegerComparision, list1, list2);
39 var expectedList = GetExpectedMergedList(IntegerComparision, list1, list2);
40 Assert.AreEqual(expectedList.Count, mergedList.Count);
41 CollectionAssert.AreEqual(expectedList, mergedList);
42 }
43
44 [Test]
45 public void Merge2TestNoOverlap2()
46 {
47 var list1 = new List<int> {100, 50, 20, 10, 1};
48 var list2 = new List<int> {500, 300, 250, 150, 120};
49 var mergedList = CollectionUtils.MergeSortedLists(IntegerComparision, list1, list2);
50 var expectedList = GetExpectedMergedList(IntegerComparision, list1, list2);
51 Assert.AreEqual(expectedList.Count, mergedList.Count);
52 CollectionAssert.AreEqual(expectedList, mergedList);
53 }
54
55 private static IList<T> GetExpectedMergedList<T>(Comparison<T> comparision, params IList<T>[] lists)
56 {
57 var set = new SortedSet<T>(new ComparisionComparer<T>(comparision));
58 foreach (var list in lists)
59 {
60 foreach (var item in list)
61 {
62 if (!set.Contains(item))
63 {
64 set.Add(item);
65 }
66 }
67 }
68 return set.ToList();
69 }
70
71 private static int IntegerComparision(int x, int y)
72 {
73 return y - x;
74 }
75
76 private class ComparisionComparer<T> : IComparer<T>
77 {
78 private readonly Comparison<T> _comparision;
79
80 public ComparisionComparer(Comparison<T> comparision)
81 {
82 _comparision = comparision;
83 }
84
85 public int Compare(T x, T y)
86 {
87 return _comparision(x, y);
88 }
89 }
90 }
91 }

list数组归并去重的更多相关文章

  1. C#两路list数组归并去重

    两个相同类型已排序数据进行合并,虽然list数组中有AddRange方法,但它只是把第二个数组从第一个数组末尾插入,假如两个数组有重复数据,保存进去.还有Union方法合并去重,首先会从第一个数组进行 ...

  2. PHP数组合并+与array_merge的区别分析 & 对多个数组合并去重技巧

    PHP中两个数组合并可以使用+或者array_merge,但之间还是有区别的,而且这些区别如果了解不清楚项目中会要命的! 主要区别是两个或者多个数组中如果出现相同键名,键名分为字符串或者数字,需要注意 ...

  3. JS中数组对象去重

    JS数组去重 JS中对数组去重最好不要用unique方法,该方法主要是对dom节点数组的去重,如果对普通的数组元素去重只会去掉与之相邻的重复元素,也就是如果数组中还有不相邻的重复元素存在,将不会被去掉 ...

  4. PHP合并数组及去重

    本文介绍的是一维数组的去重 合并数组的方法 array_merge: 数字键,直接往后添加,key重置 字符串键,后面的数组的值会替代前面的值 +: 数字键,后面的数组的值不会替代前面的值 字符串键, ...

  5. 总结Javascript中数组各种去重的方法

    相信大家都知道网上关于Javascript中数组去重的方法很多,这篇文章给大家总结Javascript中数组各种去重的方法,相信本文对大家学习和使用Javascript具有一定的参考借鉴价值,有需要的 ...

  6. [JAVA]JAVA章1 数组数据去重

    一 利用HashSet进行去重 //定义一个数组:有几个重复项 int[] testarray = {1,2,33,4,2,3,44,5,222,3}; //利用HashSet对数组数据去重 Set& ...

  7. 合并两个数组并去重(ES5和ES6两种方式实现)

    合并两个数组并去重(ES5和ES6两种方式实现) ES6实现方式 let arr1 = [1, 1, 2, 3, 6, 9, 5, 5, 4] let arr2 = [1, 2, 5, 4, 9, 7 ...

  8. python之数组元素去重

    参考:如何消除一个数组里面的重复元素?(面试题目) 思路,即创建一个新数组,把原数组中的元素逐个添加到新数组中(判断新数组中是否已经包含原数组中的元素,如果没有,把原数组中的元素添加到新数组,如果已经 ...

  9. JS实现对数组的去重

    JS实现对数组的去重 $scope.validateContect = function(text) { var arr = text; // 若传入的数据为string类型,用逗号分隔 if((ty ...

随机推荐

  1. 1.13 Python基础知识 - 字典和集合

    一.字典 字典是一组键-值对的数据结构.每个键对应一个值.在字典中,键不能重复.根据键可以查询到值.字典是键和值的映射关系 字典的定义: 字典通过花括号中用逗号分隔的元素(键-值.键-值对使用冒号分隔 ...

  2. mysql中配置ssl_key、ssl-cert、ssl-ca的路径及建立ssl连接(适用于5.7以下版本,5.7及以上请看本文末尾的备注)

    1.创建 CA 私钥和 CA 证书 (1)下载并安装openssl,将bin目录配置到环境变量: (2)设置openssl.cfg路径(若不设置会报错,找不到openssl配置文件) \bin\ope ...

  3. 前端面试题(HTML/CSS)

    (前端面试题大全,持续更新) 常用的块级元素和行内元素有哪些?说说他们的特点? 浮动产生的原因?清除浮动? 说说一下盒模型 float和position一起用是什么效果 rem用过吗?做不同手机的适配 ...

  4. redis 模糊删除实现

    redis 没有直接提供模糊删除的实现,我们可以根据现有的指令进行组合实现: import java.util.Arrays; import java.util.Set; import javax.a ...

  5. C++ Tricks(一)—— 判断字符串 string 对象的所有字符都相等

    S == string(S.size(), S[0]);

  6. 【拆分版】 Docker-compose构建Logstash多实例,基于7.1.0

    [拆分版]Docker-compose构建Logstash多实例 写在最前 说起Logstash,这个组件并没有什么集群的概念,与其说是集群,不如说是各自去收集日志分析过滤存储到Elasticsear ...

  7. [WASM] Write to WebAssembly Memory from JavaScript

    We write a function that converts a string to lowercase in WebAssembly, demonstrating how to set the ...

  8. struts2漏洞原理及解决的方法

    1.原理 Struts2的核心是使用的webwork框架,处理 action时通过调用底层的getter/setter方法来处理http的參数,它将每一个http參数声明为一个ONGL(这里是ONGL ...

  9. POJ 2363 Blocks (ZOJ 1910) 数学

    杨宗纬的歌"这一路走来" 还蛮好听的,这首歌静静的躺在我的音乐盒某个阴暗的角落里,今天随机播放才发现的,哈哈. 数学一直是硬伤...... -------------------- ...

  10. 如何在移动web模仿客户端给input输入框添加自定义清除按钮

    项目有个需求就是在input输入框添加清除按钮,网上查找资料加上自己琢磨终于弄出来了. 灵感来自于 http://www.zhangxinxu.com/wordpress/?p=4077 由于项目已经 ...