标签:
使用表驱动法要面临的两个问题:
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