有關《尋找兩個List中的不同元素》的問題解答與編程實踐

來源:互聯網
上載者:User
有關《尋找兩個List中的不同元素》的問題解答與編程實踐 鄭海波 2013-07-08

問題:

有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實現的話,運行速度將更快!沒事的時候再試試~~

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.