=================================版权声明=================================

版权声明:本文为博主原创文章 未经许可不得转载 

请通过右侧公告中的“联系邮箱(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之类的样子,不过我不喜欢。

=======================================================================

其实我是个轮子制造家。