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 }
转载于:https://www.cnblogs.com/Nicolas-wang/p/4685933.html
C#两路list数组归并去重相关推荐
- 对两个有序数组重新去重合并排序js实现
这里主要是要利用两个数组有序这个条件,所以只需两个指针分别指向两个数组,当其中一个小于另外一个就移动该指针,反之则移动另外一个指针,如果相等则均向后移动. 结束条件是,当任意一个数组的指针移到末尾则跳 ...
- java json 去重_js操作两个json数组合并、去重,以及删除某一项元素
两个json数组合并去重,以及删除某一项元素 let ha = [ {id:'H',name:'3'}, {id:'A',name:'6'}, {id:'B',name:'14'}, {id:'C', ...
- JS:两个json数组合并、去重,以及删除某一项元素
两个json数组合并去重,以及删除某一项元素 let ha = [{id:'H',name:'3'},{id:'A',name:'6'},{id:'B',name:'14'},{id:'C',name ...
- php 两个二维数组怎么去重,php 二维数组怎么不去重合并
php二维数组不去重合并的方法:首先创建一个PHP示例文件:然后创建两个二维数组:最后通过"array_merge_recursive"函数合并数组即可. 本文操作环境:Windo ...
- php 合并两个数组并去重,合并两个数组 以KEY 作为键
$a= array( array( 'ID'=> 2 ) ); $b= array( array( 'ID'=> 5656 ) ); print_r($r); //合并两个数组 以ID值 ...
- 两个对象数组去重的3种方法
两个对象数组去重的3种方法 前言 问题描述 解决方案一 解决方案二 解决方案三 前言 前段时间写过JavaScript数组去重最简单的 4 种方案,里面的数组元素是基本类型.本文要讲的数组元素是对象, ...
- php两个数组之间去重,php数组去重、魔术方法、redis常用数据结构及应用场景
一.用函数对数组进行去重的方法 1. arrau_unique函数的作用 移除数组中重复的值. 将值作为字符串进行排序,然后保留 每个值第一次 出现的健名,健名保留不变. 第二个参数可以选择排序方式: ...
- c语言 数组二合一,C语言合并两个数组并去重
下面是编程之家 jb51.cc 通过网络收集整理的代码片段. 编程之家小编现在分享给大家,也给大家做个参考. 给定含有m.n个元素的两个有序(非降序)整型数组a和b. 合并两个数组中的元素到整型数组c ...
- android两个数组对象去重合并,JS 两个对象数组合并并去重
JS两个对象数组合并并去重 let jsonArr = [ { "ID": "", "NO": "1", "N ...
- android两个数组对象去重合并,js 两个数组(对象)去重合并
项目前台代码中需要用到数组的去重操作,其实也不难,就算是对象数组,判断下对应的属性值也是可以实现的,但是如果我实现的话肯定是最常见的双重for循环,加个flag标记,老套的不能行了,想了想,还是上网找 ...
最新文章
- R语言删除包含缺失值的行并将字符数据列(character)转化为因子列(factor)实战
- java + httpclient +post请求(记录下)
- cassandra 入门_Apache Cassandra和Java入门(第二部分)
- 开源开放 | 图数据交互可视化分析框架 InteractiveGraph v0.3 版本发布
- Try Redis : Redis 入门教程
- opencv图像-拼接线的处理
- 关于git clone 下载apex 过程中,缺少libssl.so.1.0.0的问题
- 11组软件工程组队项目失物招领系统——界面设计文档
- 聊聊我所从事过的通信行业
- 莱布尼茨公式C语言编程,高等数学——手撕牛顿莱布尼茨公式
- 华为 hg8245c 超级密码
- 微服务项目:尚融宝(38)(核心业务流程:申请借款额度(2))
- Word中的SVG格式的矢量插图问题
- 一款在线免费的甘特图,让你轻松管理项目进度
- 非常简单-Linux环境下(有公网IP)或虚拟主机的环境下如何做一个网站???
- python+appium自动化测试-获取短信+图片验证码
- Windows 下使用pip install 安装出现报错ERROR: Cannot unpack file解决办法
- 组FreeNas11.3的一点心得
- 【汇正财经顾晨浩】建筑行业,一带一路合作深化
- 辅助继电器的作用与类型 如何区分直流和交流继电器