摘要:轉換為社保卡和,從二者中找出匹配的社保卡。準備初始化數據小明小紅小王小目標從中篩選出中存在的卡片遍歷很容易看出,時間復雜度采用通過觀察發現,兩個取相同的部分時,每次都遍歷兩個。
問題
現有社保卡和身份證若干,想要匹配篩選出一一對應的社保卡和身份證。
轉換為List<社保卡> socialList,和List
創建社保卡類
/** * @author Ryan Miao */ class SocialSecurity{ private Integer id;//社保號碼 private Integer idCard;//身份證號碼 private String somethingElse; public SocialSecurity(Integer id, Integer idCard, String somethingElse) { this.id = id; this.idCard = idCard; this.somethingElse = somethingElse; } public Integer getId() { return id; } public Integer getIdCard() { return idCard; } public String getSomethingElse() { return somethingElse; } @Override public String toString() { return "SocialSecurity{" + "id=" + id + ", idCard=" + idCard + ", somethingElse="" + somethingElse + """ + "}"; } }
創建身份證類
class IdCard { private Integer id;//身份證號碼 private String somethingElse; public IdCard(Integer id, String somethingElse) { this.id = id; this.somethingElse = somethingElse; } public Integer getId() { return id; } public String getSomethingElse() { return somethingElse; } @Override public String toString() { return "IdCard{" + "id=" + id + ", somethingElse="" + somethingElse + """ + "}"; } }最簡單的辦法:遍歷
只要做兩輪循環即可。
準備初始化數據:
private ArrayListsocialSecurities; private ArrayList idCards; @Before public void setUp(){ socialSecurities = Lists.newArrayList( new SocialSecurity(1, 12, "小明"), new SocialSecurity(2, 13, "小紅"), new SocialSecurity(3, 14, "小王"), new SocialSecurity(4, 15, "小peng") ); idCards = Lists.newArrayList( new IdCard(14, "xiaopeng"), new IdCard(13, "xiaohong"), new IdCard(12, "xiaoming") ); //目標: 從socialSecurities中篩選出idCards中存在的卡片 }
遍歷
@Test public void testFilterForEach(){ Listresult = new ArrayList<>(); int count = 0; for (SocialSecurity socialSecurity : socialSecurities) { for (IdCard idCard : idCards) { count++; if (socialSecurity.getIdCard().equals(idCard.getId())){ result.add(socialSecurity); } } } System.out.println(result); System.out.println(count);//12 = 3 * 4 //O(m,n) = m*n; }
很容易看出,時間復雜度O(m,n)=m*n.
采用Hash通過觀察發現,兩個list取相同的部分時,每次都遍歷兩個list。那么,可以把判斷條件放入Hash中,判斷hash是否存在來代替遍歷查找。
@Test public void testFilterHash(){ Setids = idCards .stream() .map(IdCard::getId) .collect(Collectors.toSet()); List result = socialSecurities .stream() .filter(e->ids.contains(e.getIdCard())) .collect(Collectors.toList()); System.out.println(result); //初始化 hash 3 //遍歷socialSecurities 4 //從hash中判斷key是否存在 4 //O(m,n)=2m+n=11 }
如此,假設hash算法特別好,hash的時間復雜度為O(n)=n。如此推出這種做法的時間復雜度為O(m,n)=2m+n. 當然,更重要的是這種寫法更讓人喜歡,天然不喜歡嵌套的判斷,喜歡扁平化的風格。
Hash一定會比遍歷快嗎想當然的以為,hash肯定會比遍歷快,因為是hash啊。其實,可以算算比較結果。比較什么時候2m+n < m*n。
從數據歸納法的角度,n必須大于2,不然即演變程2m+2 < 2m。于是,當n>2時:
@Test public void testCondition(){ int maxN = 0; for (int m = 2; m < 100; m++) { for (int n = 3; n < 100; n++) { if ((2*m+n)>m*n){ System.out.println("m="+m +",n="+n); if (n>maxN){ maxN = n; } } } } System.out.println(maxN); }
結果是:
m=2,n=3 3
也就是說n<=3的時候,遍歷要比hash快。事實上還要更快,因為hash還需要創建更多的對象。然而,大部分情況下,n也就是第二個數組的長度是大于3的。這就是為什么說hash要更好寫。當然,另一個很重要的原因是lambda stream的運算符號遠比嵌套循環讓人喜愛。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/67645.html
摘要:起步本章介紹如何不利用第三方庫,僅用自帶的標準庫來構造一個決策樹。構造決策樹決策樹中需要一個屬性來指向樹的根節點,以及特征數量。 起步 本章介紹如何不利用第三方庫,僅用python自帶的標準庫來構造一個決策樹。不過這可能需要你之前閱讀過這方面的知識。 前置閱讀 分類算法之決策樹(理論篇) 分類算法之決策樹(應用篇) 本文使用將使用《應用篇》中的訓練集,向量特征僅有 0 和 1 兩種情況...
摘要:如何管理項目的數據這個問題似乎早已經有答案了,無非就是使用,全局,整個應用維護一個超大的,界面的顯示情況隨著超大的變化而變化。 vuex 如何管理 vue 項目的數據?這個問題似乎早已經有答案了,無非就是使用 vuex ,全局 store,整個應用維護一個超大的 Object,界面的顯示情況隨著超大 Object 的變化而變化。 看起來很簡單,不就維護一個 Object 嘛,實際上,要...
摘要:編程規范筆記上寫在前面從語言開始,自己陸續學習了,但是自從研究生做畢設接觸以來,就愛不釋手,再也沒有動力嘗試其他語言。一與的一大優勢就是具備優秀的可讀性,而這基于一套較為完整的公認編程規范。如原本希望的結果是,結果卻完全一樣。 Python編程規范筆記(上) 寫在前面: 從C語言開始,自己陸續學習了C++/Java,但是自從研究生做畢設接觸Python以來,就愛不釋手,再也沒有動力嘗試...
閱讀 3840·2021-10-12 10:12
閱讀 1471·2021-10-11 10:58
閱讀 2307·2021-10-09 10:01
閱讀 2620·2021-09-24 09:48
閱讀 2715·2021-09-09 11:38
閱讀 3538·2019-08-30 15:44
閱讀 1737·2019-08-30 14:22
閱讀 530·2019-08-29 12:42