=================================版权声明=================================
版权声明:本文为博主原创文章 未经许可不得转载
请通过右侧公告中的“联系邮箱(wlsandwho@foxmail.com)”联系我
未经作者授权勿用于学术性引用。
未经作者授权勿用于商业出版、商业印刷、商业引用以及其他商业用途。
本文不定期修正完善,为保证内容正确,建议移步原文处阅读。 <--------总有一天我要自己做一个模板干掉这只土豆
本文链接: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之类的样子,不过我不喜欢。
=======================================================================
其实我是个轮子制造家。