有关《查找两个List中的不同元素》的问题解答与编程实践
来源:互联网 发布:mac如何用鼠标复制粘贴 编辑:程序博客网 时间:2024/05/16 16:58
有关《查找两个List中的不同元素》的问题解答与编程实践
问题:
有List<String> list1和List<String> list2,两个集合各有上万个元素,怎样查找两个集合中不同的元素呢?
问题分析:
由于每个list中都有上万个元素,如果用简单的遍历查找算法,那么至少需要10000*10000次判断比较。显然,这样做的效率极低。那么有没有比较好的方案呢?经过我的思考,想出了2个办法。请大家评判。
方法一:遍历算法的改进算法
思路:对每一个list1中的元素,都在list2中查找一下,是否重复,如果不重复,则将该元素放到listDiff中。如果重复,则将该元素从list2中剔除。这样,能够减少遍历算法的时间复杂度,而且重复元素越多,该改进算法的运行时间就越短。当然,如果两个list的重复元素个数远远小于list的长度,则该算法的时间复杂度和遍历算法近似相同,会变的很慢而不切实际。
方法二:利用Map中无重复元素的特性
思路:将list1中元素首先复制到map<String,Integer>中,并将其Integer的值设置为1.然后再对list2中的元素,与map中元素比较。如果map中已经存在该String,那么map中对应String的Integer加1(表示字符串出现的次数),如果map中不存在,那么就将其复制到map中,并设置其Integer为1.那么,map中Integer值为1的元素所对应的String,就是两个list中不同的元素。
以下代码是在Java中实现,也可以用C++ STL进行测试。
import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;/* *@author: ZhengHaibo *2013-07-08 Nanjing,Conris,China */ public class TestMian {private static final int ListLen = 10000;// 设置list的长度private static final Integer flagUnique = 1;//无重复字符串的键值public List<String> list1 = new ArrayList<String>();public List<String> list2 = new ArrayList<String>();public static void main(String[] args) {// TODO Auto-generated method stubTestMian mTest=new TestMian();mTest.initList();List<String> listDiff1=mTest.getDiffElementUseEach(mTest.list1,mTest.list2);//获得不同元素mTest.initList();List<String> listDiff2=mTest.getDiffElementUseMap(mTest.list1,mTest.list2);//获得不同元素System.out.println("The number of diff element is: "+listDiff1.size());System.out.println("The number of diff element is: "+listDiff2.size());//mTest.printList(listDiff1);//mTest.printList(listDiff2);}// 初始化list中的元素,并保证有相同的元素public void initList() {list1.clear();list2.clear();for (int i = 0; i < ListLen; i++) {list1.add("conris_list_of" + i + "test");list2.add("conris_list_of" + 3 * i + "test");}}//获得连个list中的不同元素,查找删除法public List<String> getDiffElementUseEach(List<String> list1,List<String> list2) {System.out.println("-----------------------方法1----------------------");long runtime = System.nanoTime();// 开始计时List<String> diffList = new ArrayList<String>();// 用于保存两个list中不同的元素for (String string:list1) {//消除list1本身的重复元素int index=list2.indexOf(string);if (index==-1) {//说明list2中不存在此元素diffList.add(string);}else{//list2存在此元素,那么删除此元素list2.remove(index);}}for(String string:list2){//此时,liat2中的重复元素已经删除了,只需要复制到diffList中即可diffList.add(string);}System.out.println("getDiffElementUseRemove run time:"+ (System.nanoTime() - runtime));return diffList;}//获得两个list中的不同元素,map方法public List<String> getDiffElementUseMap(List<String> list1,List<String> list2){System.out.println("-----------------------方法2----------------------");long runtime = System.nanoTime();//开始计时//利用map中不能有重复元素的特点Map<String, Integer> map = new HashMap<String,Integer>(list1.size()+ list2.size());List<String> diffList = new ArrayList<String>();//用于保存两个list中不同的元素for (String string : list1) {map.put(string,flagUnique);//先将list1中元素复制到map中保存}for (String string : list2) {Integer key = map.get(string);// 获得键值if (key != null) {//如果map中已经存在该元素,说明list1中存在该元素,那么将其key加1map.put(string, ++key);continue;}else{//如果不存在,则放入map中map.put(string,flagUnique);}}for (Map.Entry<String, Integer> entry : map.entrySet()){if (entry.getValue() == flagUnique)//在map中,键值为flagUnique的元素即为无重复的元素{diffList.add(entry.getKey());}}System.out.println("getDiffElementUseMap run time:"+ (System.nanoTime() - runtime));return diffList;}public void printList(List<String> list){for(int i=0;i<list.size();i++){System.out.println(list.get(i));}}}
实验结果:
当ListLen设置为10000时:
结果1:
-----------------------方法1----------------------getDiffElementUseRemove run time:2015792051-----------------------方法2----------------------getDiffElementUseMap run time:37966034The number of diff element is: 13332The number of diff element is: 13332
当ListLen设置为100000时:等了半天方法1没有运行出来结果,方法2的运行结果如下:
-----------------------方法2----------------------getDiffElementUseMap run time:471017640The number of diff element is: 133332
可见当数据量达到100000时(增大10倍),方法二仍然可以工作,而且时间也随着数据量增大线性增加。
而方法1很久也没有运行出来结果…
由此可见,利用HashMap的方法速度更快,能够满足基本要求。不知道大家还有哪些想法可以交流交流。希望对大家有帮助。
PS:如果用C++ STL实现的话,运行速度将更快!没事的时候再试试~~
- 有关《查找两个List中的不同元素》的问题解答与编程实践
- 比较两个List元素是否相同,查找出两个list的不同元素
- 高效的找出两个List中的不同元素
- 高效的找出两个List中的不同元素
- 高效的找出两个List中的不同元素
- 高效的找出两个List中的不同元素
- 高效的找出两个List中的不同元素
- 高效的找出两个List中的不同元素
- 高效的找出两个List中的不同元素
- 高效筛选两个List中的不同的元素
- 快速计算两个List的不同元素
- Java 查找两个有复杂对象的集合中的不同元素和相同的元素
- 找出list中的不同元素、删除两个list中相同的对象
- Java中找到两个list中的不同元素
- setdiff:查找两个向量中不同的元素 + 外两则
- 高效找出两个List中不同的元素
- MATLAB中查找两个不同维度的矩阵中相同或者不同元素的位置
- 有关List查找的问题
- linux笔试题
- 给sqlite加个了vs2005的工程
- 流弊的宏定义们。。。持续更新
- 二进制及逻辑运算学习
- 查看局域网内所有ip地址
- 有关《查找两个List中的不同元素》的问题解答与编程实践
- 毕业答辩完来北京
- 著名半导体厂商
- 安装dotnetframework3.5无需联网的方法
- 11. jsp与servlet之间页面跳转及参数传递实例
- 提高你的Java代码质量吧:三元操作符的类型陷阱
- 临界区
- 放弃MySQL的五大理由
- Google HTML/CSS 风格指南