list数组归并去重
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数组归并去重的更多相关文章
- C#两路list数组归并去重
两个相同类型已排序数据进行合并,虽然list数组中有AddRange方法,但它只是把第二个数组从第一个数组末尾插入,假如两个数组有重复数据,保存进去.还有Union方法合并去重,首先会从第一个数组进行 ...
- PHP数组合并+与array_merge的区别分析 & 对多个数组合并去重技巧
PHP中两个数组合并可以使用+或者array_merge,但之间还是有区别的,而且这些区别如果了解不清楚项目中会要命的! 主要区别是两个或者多个数组中如果出现相同键名,键名分为字符串或者数字,需要注意 ...
- JS中数组对象去重
JS数组去重 JS中对数组去重最好不要用unique方法,该方法主要是对dom节点数组的去重,如果对普通的数组元素去重只会去掉与之相邻的重复元素,也就是如果数组中还有不相邻的重复元素存在,将不会被去掉 ...
- PHP合并数组及去重
本文介绍的是一维数组的去重 合并数组的方法 array_merge: 数字键,直接往后添加,key重置 字符串键,后面的数组的值会替代前面的值 +: 数字键,后面的数组的值不会替代前面的值 字符串键, ...
- 总结Javascript中数组各种去重的方法
相信大家都知道网上关于Javascript中数组去重的方法很多,这篇文章给大家总结Javascript中数组各种去重的方法,相信本文对大家学习和使用Javascript具有一定的参考借鉴价值,有需要的 ...
- [JAVA]JAVA章1 数组数据去重
一 利用HashSet进行去重 //定义一个数组:有几个重复项 int[] testarray = {1,2,33,4,2,3,44,5,222,3}; //利用HashSet对数组数据去重 Set& ...
- 合并两个数组并去重(ES5和ES6两种方式实现)
合并两个数组并去重(ES5和ES6两种方式实现) ES6实现方式 let arr1 = [1, 1, 2, 3, 6, 9, 5, 5, 4] let arr2 = [1, 2, 5, 4, 9, 7 ...
- python之数组元素去重
参考:如何消除一个数组里面的重复元素?(面试题目) 思路,即创建一个新数组,把原数组中的元素逐个添加到新数组中(判断新数组中是否已经包含原数组中的元素,如果没有,把原数组中的元素添加到新数组,如果已经 ...
- JS实现对数组的去重
JS实现对数组的去重 $scope.validateContect = function(text) { var arr = text; // 若传入的数据为string类型,用逗号分隔 if((ty ...
随机推荐
- 12、python单步调试工具pdb
pdb 第4种方式是启动Python的调试器pdb,让程序以单步方式运行,可以随时查看运行状态.我们先准备好程序: # err.py s = '0' n = int(s) print(10 / n) ...
- [python]-类与对象-上
[类]是一个函数包.类中可以放置函数和变量,然后类中的函数可以很方便的使用类中的变量 1.类的定义 2.类中方法的调用 在类中被定义的函数被称为类的[方法],描述的是这个类能做什么.我们使用类名.函数 ...
- [React] Configure a React & Redux Application For Production Deployment and Deploy to Now
In this lesson, we’ll make a few small changes to our scripts and add some environment variables tha ...
- HTML、XHTML、css速记
一.HTML 下面内容记录经常使用的html元素.可另存为html文件以查看效果: <!doctype html> <html lang="zh-cn"> ...
- C#中防止程序多次运行
C#中如何防止程序多次运行?只要在程序入口点函数Main()中的开始部分添加如注释部分的代码,就能快捷实现. 示例代码如下: using System; using System.Collecti ...
- hadoop组件及其作用
1.hadoop有三个主要的核心组件:HDFS(分布式文件存储).MAPREDUCE(分布式的计算).YARN(资源调度),现在云计算包括大数据和虚拟化进行支撑. 在HADOOP(hdfs.MAPRE ...
- python中如何在一张图上画两条折线
摘自:https://segmentfault.com/q/1010000002760775
- error app/styles/components/iconfont.scss (Line 12: Invalid GBK character "\xE5")
因为要用到iconfont,引入iconfont到sass文件后,出现编译sass文件错误,如下截图: 解决方法:在顶部设置编码格式 @charset "utf-8"; 编译成功!
- spark提交应用的方法(spark-submit)
参考自:https://spark.apache.org/docs/latest/submitting-applications.html 常见的语法: ./bin/spark-submit \ ...
- Android学习笔记(20):时钟(AnalogClock和TextClock)和计时器(Chronometer)
时钟文本TextClock继承自TextView.是用于显示当前时间的文本框. TextClock支持的XML属性和相关方法 XML属性 相关方法 说明 android:format12Hour se ...