表驱动法(Table-Driven )在程序中应用

Table-drive表驱动法--由税率问题引出

皮贝贝 posted @ 2008年7月05日 21:38 in 模式之灾 with tags 表驱动法 c++ , 3732 阅读

 问题引出:写一个医疗保险费率的程序,这些费率是随着年龄、性别、婚姻状况的不同情况而变化。

一般思路:我们可能会想到条件分支,好我们先看看条件分支的情况:

 

  1. if ( gendar == Male )
  2. {
  3.         if ( maritalStatus == Single )
  4.         {
  5.                 if ( age < 18 )
  6.                 {
  7.                         rate = 80.00;
  8.                 }
  9.                 else if ( age < 30 )
  10.                 {
  11.                         rate = 90.00;
  12.                 }
  13.                 //.......其他略
  14.         }
  15.         else if ( maritalStatus == Maried )
  16.         {
  17.                 //又是一串年龄判断分支
  18.         }
  19. }
  20. else if ( gendar == Female )
  21. {
  22.         //又是一串婚姻状况判断分支
  23. }
  24.  
  25.  

      可以看到上述的条件分支程序,写起来有多,读起来也是有些费时间,而且万一改动一点,比如增加一个婚姻状况(当然这是不可能的了,不过我们还是有时会面临这种类似的扩充),还要在增加好多代码。一个稍微明智的人可能会改为switch语句,这样看其来更易读些,还是难逃条件分支语句的缺陷。

     Table-drive 表驱动法是一种替代逻辑语句(if / else)的编程模式,其替代优点是简单清晰,尤其是在判断分支较多的情况时, 另一个显在的优势是可以放在文件中读取,这样一来,就可以就可以不改变源代码前提下更改一些表内容,正合元编程思想。

   
大而论之,三则:

1. 直接访问表
2. 索引访问表
3. 阶梯访问表
 

    下面我们就税率问题看看用表驱动法是如何解决的。

  先看看直接访问表法:把所有的税率放在数组的表中,其他的访问条件如年龄,婚姻状况,性别可以用数组下标来表示,我们先构建几个数据结构:

 

  1.  
  2. enum Gendar
  3. {
  4.         GendarFirst     =     0,
  5.         GendarMale      =     0,
  6.         GendarFemal     =     1,
  7.         GendarLast      =     1
  8. };
  9.  
  10. enum MaritalStatus
  11. {
  12.         MaritalStatusFirst      =     0,
  13.         MaritalStatusSingle     =     0,
  14.         MaritalStatusMarried    =     1,
  15.         MaritalStatusLast       =     1
  16. };
  17.  

因此我们的税率表就自然构造好了:

 

  1. double rateTable[GendarLast][MaritalStatusLast][MAX_AGE];

MAX_AGE是一个年龄最大值,每个年龄都有一个对应的税率。

我们可以正式用它了,看看怎么调用它吧:

 

  1. double rate = rateTable[gemdar][maritalStatus][age];

调用比起用条件分支判断语句简单吧。

 

上面我们讲到,每个年龄都有一个对应的税率,但是税率是按年龄段来分的,所以上述的直接访问表法有很多冗余信息,造成了空间浪费。

解决方法是我们可以加一个中间层,我们加了一个年龄转化函数,用来把实际年龄转化为一个年龄段,这样调用接口就变成了这样:

 

  1.  
  2. double getRate( Gendar gemdar, MaritalStatus maritalStatus, int age )
  3. {
  4.         int ageIndex = getAgeIndex( age );
  5.         return rateTable[gemdar][maritalStatus][ageIndex];
  6. }
  7.  

当然,在税率的表中,第三个数组下标就从年龄变成了年龄段:

 

  1. double rateTable[GendarLast][MaritalStatusLast][MAX_AGE_INDEX];

剩下的是我们如何实现中间层,我们就再增加一个数组表,:

 

  1.  
  2. int ageIndex[MAX_AGE_INDEX] = {020, 50, 60, 70, 80};
  3.  
  4. int getAgeIndex( int age )
  5. {
  6.         int iPos;
  7.         while ( ageIndex[iPos] < age ) iPos++;
  8.         return iPos-1;
  9. }

 

表驱动法是编程初学者的强大武器,可以在表中放元素,亦可以放函数指针,只要是有分支判断的地方几乎都可以一试拳脚。

Avatar_small
jnanabhumiap.in 说:
2024年1月22日 15:16

JNANABHUMI AP provides all latest educational updates and many more. The main concept or our aim behind this website has been the will to provide resources full information on each topic which can be accessed through Internet. To ensure that every readers get’s what important and worthy about the topic they search and link to hear from us. jnanabhumiap.in Jnanabhumi AP is a startup by passionate webmasters and bloggers who have passion to provide engaging content which is accurate, interesting and worthy to read. We are mope like a web community where you can find different information’s, resources, topics on day to day incidents or news. We provide you the finest of web content on each and every topics possible with help of editorial and content team.


登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter