码迷,mamicode.com
首页 > 其他好文 > 详细

表驱动法举例

时间:2015-06-29 19:31:50      阅读:130      评论:0      收藏:0      [点我收藏+]

标签:

使用表驱动法要面临的两个问题:

1. 如何访问表?可选的方式有直接访问、索引访问和阶梯访问。

2. 表中存什么?如果要得到的是数据,则将数据放进表中;如果要得到的是某个动作,则将函数指针放进表中。

例1:给定分数评出等级,保证分数范围在0-100内,规定90-100分等级为A,80-89为B,70-79为C,60-69为D,0-59为E。

函数原型为:char GetGrade(int score);

一般做法

1 char GetGrade(int score)
2 {
3     if (score >= 90) return A;
4     if (score >= 80) return B;
5     if (score >= 70) return C;
6     if (score >= 60) return D;
7     return E;
8 }

使用表驱动法

 1 struct mark
 2 {
 3     int lower;  // 分数区间下界
 4     int grade;  // 分数对应等级
 5 };
 6 
 7 const struct markTable[] =
 8 {
 9     {90, A},
10     {80, B},
11     {70, C},
12     {60, D},
13     {0,  E},
14 };
15 
16 int GetIndex(int score)
17 {
18     int idx = 0;
19     while (score < table[idx].lower)
20         idx++;
21     return idx;
22 }
23 
24 char GetGrade(int score)
25 {
26     int idx = GetIndex(score);
27     return markTable[idx].grade;
28 }

上面查表时采用的线性查找,如果表数据比较多,可考虑用二分查找,但前提是表有序。

例2:某系统在校验用户身份有效性时提供多种认证方式,如静态密码、指纹、动态令牌、LDAP、Radius等。现在为了提高系统安全,需要在原认证基础上扩展出双重认证,即任选两种不同的认证方式组合,当且仅当两种认证方式都校验通过才认为身份有效。

说明:认证类型authType为int类型,从低位到高位分别代表静态密码、指纹、动态令牌、LDAP、Radius认证方式,如4代表动态令牌认证,9代表LDAP和静态密码双重认证。

输入数据格式为:

普通认证:username password

双重认证:username password1 password2,其中password1与password2顺序不做要求。

各种认证的函数原型列出如下,具体认证过程略。

1 int AuthByPwd(const char *user, const char *pass);
2 int AuthByFingerprint(const char *user, const char *pass);
3 int AuthByToken(const char *user, const char *pass);
4 int AuthByLdap(const char *user, const char *pass);
5 int AuthByRadius(const char *user, const char *pass);

使用表驱动法实现双重认证

 1 typedef int (*AuthFunc)(const char *, const char*);
 2 
 3 int Offset(unsigned n)
 4 {
 5     int offset;
 6 
 7     for (offset = 0; n; n >>= 1, offset++);
 8     return offset;
 9 }
10 
11 int main()
12 {
13     const static AuthFunc authFunc[] = {
14         NULL,
15         AuthByPwd,
16         AuthByFingerprint,
17         AuthByToken,
18         AuthByLdap,
19         AuthByRadius,  
20     };
21     int authType, ret, idx[2] = {0};
22     char user[32], pass1[32], pass2[32];
23     
24     while (~scanf("%d", &authType)) {
25         if (authType & (authType - 1)) {
26             scanf("%s%s%s", user, pass1, pass2);
27             idx[0] = Offset(authType & -authType);
28             authType &= authType - 1;
29             idx[1] = Offset(authType & -authType);
30             ret = (authFunc[idx[0]](user, pass1) && authFunc[idx[1]](user, pass2))
31                || (authFunc[idx[0]](user, pass2) && authFunc[idx[1]](user, pass1));
32         } else {
33             scanf("%s%s", user, pass1);
34             idx[0] = Offset(authType & -authType);
35             ret = authFunc[idx[0]](user, pass1);
36         }
37         printf("auth %s\n", ret ? "success" : "fail");
38     }
39     return 0;
40 }

 

表驱动法举例

标签:

原文地址:http://www.cnblogs.com/boyfaceone/p/4607675.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!