=================================版權聲明=================================
版權聲明:本文為博主原創文章 未經許可不得轉載
請通過右側公告中的“聯系郵箱([email protected])”聯系我
未經作者授權勿用於學術性引用。
未經作者授權勿用於商業出版、商業印刷、商業引用以及其他商業用途。
本文不定期修正完善,為保證內容正確,建議移步原文處閱讀。 <--------總有一天我要自己做一個模板干掉這只土豆
本文鏈接:http://www.cnblogs.com/wlsandwho/p/4736084.html
恥辱牆:http://www.cnblogs.com/wlsandwho/p/4206472.html
=======================================================================
這篇文章基於STL容器,並不能面向“HelloWorld”讀者。
=======================================================================
因為加了好多的技術群,經常有人問一些奇怪的問題,有時間的時候當然會自己去想一想,模擬實踐嘛。
=======================================================================
先說一下為什麼會有這個方案:
假如有一個項目叫做ABC,
它是由A、B、C三個子項目組成的,
子項目A有兩條檢測規則:“+”是異常,“-”是正常,
子項目B有三條檢測規則:“+”是輕度異常,“++”是中度異常,“+++”是重度異常,“-”是正常,
子項目C有兩條檢測規則:“+”是異常,“-”是正常。
那麼問題來了:怎樣組織這個項目的組成?
又怎麼組織子項目的檢測規則?
如果又添加一個叫做AC的項目(由A和C組成)又該怎麼做?或者添加一個ABCD(由A、B、C、D組成的項目)又該如何處理?
這就是本文要說的東西。
=======================================================================
先自己想想然後再看下面我的分析,畢竟有些東西過程很重要,萬一你自己有更好的方法呢。
=======================================================================
其實本文並沒有什麼技術含量,然而,重要的是思想。
===============================小廣告====================================
求工作
部分技能:Windows平台,VC++、MFC、核心編程、SQL Server,
期望崗位:技術管理,
期望地點:青島高新區。
(不做C#,因為C#不在“MASM==>C/C++==>VC++==>C++/CLI”這個子技能樹裡。)
=======================================================================
顯然需要詳細的分析下,畢竟有的子項目會在不同的項目裡出現,對它的修改應該是同步影響的——最好是能且只能存儲1份。
=======================================================================
先從子項目入手。
子項目有若干個條件和結果
例如
A可以由正常、異常、無效組成,也可以由正常、輕度異常、中度異常、重度異常、無效組成。
那麼子項目的模型肯定是要能變化的、不限定數量。
再仔細考慮一下,重度異常就是重度異常,不存在什麼所謂的“重度異常1”、“重度異常2”、“重度異常3”之類的再次劃分,
也就是說,一個子項目的每一個條件結果都是一個不可再次分割的元素,也不可能是重復的。
所以
參考值——結果
采用map來存儲所有的判斷標准:map<參考值,結果>。
這樣一個map就代表了匿名子項目的判斷標准,只知道是一個判斷標准,但不知道是哪個子項目的。
由於一個子項目對應一套判斷標准,即
子項目名——map<參考值,結果>,
這樣就完整的表示了一個子項目的所有信息。
下面的結構表示了若干個子項目的集。
map<子項目名,map<參考值,結果>>
=======================================================================
再看復合項目
項目ABC包含了子項目A,子項目B,子項目C,所以一個項目對應了多個子項目。
項目名——map<子項目名,map<參考值,結果>>
下面的結構表示了所有的項目的詳細信息,包括了項目由哪些子項目組成、對應子項目的檢測規則、檢測規則的詳細內容。
map<項目名,map<子項目名,map<參考值,結果>>>
=======================================================================
簡單的分析就到這裡。
分析後的結果就是:
map<項目名,map<子項目名,map<參考值,結果>>>
不過,要是直接這樣用,是人都要發瘋的。對內層的訪問會嚇死人。而且VC++上編譯信息也不好看。
(我敢肯定直接用過的人都說好,不信自己動動手。不管你試不試,我反正試了。)
所以要適當的拆分一下。
=======================================================================
適當的信息冗余是可以的,用少量的冗余來得到一定的可讀性並且簡化編程,這點代價是可以接受的。
拆分的過程就是簡化上面的復雜的結構。
=======================================================================
拆分map<項目名,map<子項目名,map<參考值,結果>>>為
multimap<項目名,子項目名>
先拆掉一層map,便於進行項目名——子項目名的訪問。在添加一個set來輔助multimap統計項目名的種類,
畢竟multimap不能方便的檢索到底有多少種key。(當然你也可以不加。)
(另一個方法是把它拆分為map<項目名,set<子項目名>>,看個人心情了。)
拆分外層map其實是很重要的,只有這樣才能重用一個子項目的所有信息。
雖然這實際上是很簡單的一步。
剩下的結構不變,還是map<子項目名,map<參考值,結果>>來表示一個子項目的所有信息。
(當然內層的map<參考值,結果>也可以單獨定義拆分一下。但這個不重要。)
=======================================================================
基本分析就是這個樣子,可以
生成項目信息,只包括由哪些含子項目組成。
生成子項目信息,只包括項目名和對應的檢測規則。
分析是一回事,但編碼是另一回事。
=======================================================================
1 並不能通過子項目的數目來確定項目名。
2 一個由A、B、C、D組成的項目和由A、D、C、B組成的項目其實是一個項目。
簡要的說一說我的方法吧,只希望不丟人現眼。
1 寫一套代碼來表示具體定義,
2 寫一套代碼來表示具體使用。
=======================================================================
定義就是上面分析的結果,寫出來就行。
使用呢?就要略微分析一下了。
=======================================================================
怎樣確定若干個子項目代表的是什麼項目呢?
從數量上分,1個組成項的可能是A、B、C、D,2個組成項可能是AB、AC、AD、BC、BD、CD,三個組成項的可能是ABC、ABD、ACD、BCD,四個組成項的只能是ABCD。
從名稱上分,A、B組成的和B、A組成的都叫AB,A、B、C組成的和A、C、B組成的、(此處省略若干)、還有C、B、A組成的都叫做ABC。
=======================================================================
這樣就明朗了,我的做法是:
先看看手頭上有幾個子項目,
然後看看這幾個子項目名會組成一個什麼樣子的字符串。
這是最簡單的做法。
我用了一個小技巧,set是有序存儲的——這要求提供一個比較大小的“<”——把A、B放到set裡同B、A放到set裡的結果是一樣的。
(當然合成字符串會有一定的時間和空間消耗,也可以看心情用其他方法。)
=======================================================================
實際上,做的這兩套東西所用的額外空間在大量數據面前真的是微不足道的,關鍵是可支持後續定義的各種項目。
其實直接用數據庫也可以,為什麼我要費勁在內存裡做這麼多事情呢?
因為有時候,一件事情你能且只能做一次。並不是你想訪問數據庫就能訪問數據庫的。
好像也可以用XML之類的樣子,不過我不喜歡。
=======================================================================
其實我是個輪子制造家。