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 ...
随机推荐
- eclipse-12.04无图标,无法固定到侧边栏
今天下载了adt-bundle,但是eclipse打开以后,侧边栏显示的是一个问好,而且没办法固定到侧边栏,导致每次打开eclipse都要进入到相应目录,很麻烦.我们可以通过如下方法设置eclipse ...
- 4. Spring Boot 过滤器、监听器
转自:https://blog.csdn.net/catoop/article/details/50501688
- 97.TCP通信
运行截图: 客户端 创建通信套接字 //通信套接字,用于创建TCP连接 SOCKET socket_send; 创建tcp通信 //创建tcp通信 socket_send = socket(AF_IN ...
- Android代码模拟物理、屏幕点击事件
一.应用中模拟物理和屏幕点击事件 例如,模拟对某个view的点击事件 private void simulateClick(View view, float x, float y) { long do ...
- Javascript和jquery事件--键盘事件KeyboardEvent
Js和jq事件—键盘事件KeyboardEvent 键盘事件keydown,keypress和keyup,还需要涉及到一个文本事件textInput. keydown,keypress和keyup事件 ...
- 【AtCoder Regular Contest 082】Derangement
[链接]点击打开链接 [题意] 在这里写题意 [题解] 贪心. 连续一块的p[i]==i的话,对答案的贡献就应该为(这个连续块的长度+1)/2; 长度为1的也正确. (也即两两相邻的互换位置.) [错 ...
- JAVA开发类似冒险岛的游戏Part1
JAVA开发类似冒险岛的游戏Part1 一.总结 二.JAVA开发类似冒险岛的游戏Part1 初学嘛) ,不过总的来说这个程序还是很有意思的.这里我重新再整理了一下,希望能帮助到其他想要开发类似程序的 ...
- 低成本开始互联网创业:探讨域名、服务器、CDN、邮箱等节流之道
互联网创业一直是个热门话题,对这个问题我也有不断的思考. 今天,探讨下如何低成本开始互联网创业. 背景 愿意冒险去创业的同志,大多是"屌丝"而非"高富帅",大多 ...
- linux cmd cp -a
cp -a 在保留原文件属性的前提下复制文件 cp -r dirname destdir 复制目录后其文件属性会发生变化 想要使得复制之后的目录和原目录完全一样,可以使用cp -a dirn ...
- js课程 5-13 js事件绑定和鼠标事件注意事项有哪些
js课程 5-13 js事件绑定和鼠标事件注意事项有哪些 一.总结 一句话总结:js代码的灵魂就是改变标签的属性和样式,就这两种. 1.js触发改的东西是哪两样? 属性和样式 2.js如何让页面用标 ...