表驱动法 (Table Driven Approach)

表驱动法简单来说就是把原来须要用类似 switch-case 之类语句来做的事用表的对应关系来做。

它是初学者必备的武器。

 

查表的方式:
   在使用表驱动法的时候必须要解决的一个问题就是如何查表.
我们可以用非常直接的方式查一个表,就如前面示例讲的我就用数组下标就好了,但你发现有谁查字典甚至《数学用表》是直接依靠页码来查的吗?这是肯定行不通的。
常用的查表方式有

  •     直接查询
  •     索引查询
  •     分段查询

1 直接查询
直接查询,是指无需绕圈子,用下标的方式就能顺利的获取到数据;

 if(day==1)
  {
   dayName="星期一";
 }
 else if(day==2)
  {
   dayName="星期二";
 }
 
 else if(day==0)
  {
   dayName="星期日";
 
 }

 实现同样的功能,我们可以将这些数据存储到一个表里

C#代码 表驱动法获取星期名称
string[] dayNames=new string[]{"星期日","星期一","星期二","星期三","星期四","星期五","星期六"};
 
 dayName=dayNames[day];


只要一条语句就可以代替长长的if-else语句

如果某一天我们的网站要根据访客选择的语言来显示星期几 的话
表驱动法仍然很简单

C#代码 表驱动法获取星期名称
  dayName=dayNames[day, (int)GetUserLanguage() ];

但如果是用if-else的话,那长度可就的翻番啊。

 

2 索引查找
在用一个简单方法无法将“英文单词”这样数据转换成表下标时,可以考虑使用索引来查找.在.net中的Dictionary<K,V> 就是一个典型的例子

C#代码 获取一个用户对象
 Dictionary<string,User> users=GetAllUsers();
User tom=users["Tom"];


其实我们常用的DataTable就可以用索引查找的方式来获取数据

假如有个人员信息的table

C#代码 用索引查找方式从DataTable中获取第一个用户的姓名
 DataTable userInfo=dal.GetAllUsersInfo();
name=userInfo.Rows[0].Columns["UserName"];


使用索引查询的主要优点就是代码的可读性大为增强 , 可维护性也更好

C#代码 用直接查找方式从DataTable中获取第一个用户的姓名
 DataTable userInfo=dal.GetAllUsersInfo();
name=userInfo.Rows[i].Columns[3];

对比上一段代码,columns[3]很让人不知所谓;此外如果返回的Datable返回的列顺序改变的话就必须更改魔术数字3,否则代码就会出错;

 

3 分段查找
分段查找通过确定数据所处的范围确定分类(下标)
使用分段查找,需要先把每一个区间的上限写在一个表中,然后通过循环确定所处的区段,最后获得相应的等级
C#示例 根据分数查绩效等级

 

  class Calc
    {
        private static double[] rangeLimit = { 50.0, 65.0, 75.0, 90.0, 100.0 };
        private static string[] grade = { "F", "D", "C", "B", "A" };
        private static readonly int maxLevel = grade.Length - 1;
 
        public static string CalculateGrade(double score)
        {
            int level = 0;
            while (level <= maxLevel)
            {
                if (score < rangeLimit[level]) return grade[level];
                else level++;
            }
            return grade[level ];
        }
    }

 如果你的成绩是 89,那么你的等级应该是 B。上面例子很好懂。但是要注意边界的问题。这是个做范围判断的例子。

表驱动法可以让你省去一大堆令人头晕的条件判断语句,让代码看起来更优雅。本文只是让你对它有一个直观的印象,并不包含它全面的知识。它还包括 定义索引等其它的东西。比如说,上面的等级评定的示例中,负责查找等级的循环明显是程序的主要消耗所在。你可以考虑用二分法之类的方法来节省时间。如果表 中包含的元素数十分巨大怎么办?定义个索引。
最后给一个把 byte[] 转换成它对应的十六进制表示的例子。以前 CSDN 上有人问过,说为什么我用 framework 里的 MD5ServiceProvider 提供的方法来计算,得到的结果不唯一?答案是你的结果没有转换成它的等价的字符串表示。下面是 MSDN 上的方法,有了它,你再用 MD5ServiceProvider 就不会有问题了:
class HexTest
{
    static char[] hexDigits = {
        '0', '1', '2', '3', '4', '5', '6', '7',
        '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
 
    public static string ToHexString(byte[] bytes) {
        char[] chars = new char[bytes.Length * 2];
        for (int i = 0; i < bytes.Length; i++) {
            int b = bytes[i];
            chars[i * 2] = hexDigits[b >> 4];
            chars[i * 2 + 1] = hexDigits[b & 0xF];
        }
        return new string(chars);
    }
 
    static void Main() {
 
        byte[] b = {0x00, 0x12, 0x34, 0x56, 0xAA, 0x55, 0xFF};
        Console.WriteLine(ToHexString(b));
    }
}
 
 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值