搜索
查看: 4586|回复: 8

[算法] 表驱动法演示!

  [复制链接]

75

主题

849

帖子

5004

积分

六级会员

The only one

Rank: 9Rank: 9Rank: 9

积分
5004
发表于 2012-10-23 10:24:02 | 显示全部楼层 |阅读模式
本帖最后由 look 于 2012-10-23 10:34 编辑
下面这个例子主要演示表驱动法代替逻辑判断法,有兴趣的新手可以试着用判断法重新一遍,比较一下!
import win.ui;
/*DSG{{*/
mainForm = ..win.form( bottom=320;scroll=1;text=
"
表驱动法";right=394;parent=...)
mainForm.add(
radiobutton2={ dr=1;bottom=46;right=189;left=115;dt=1;top=29;z=3;text=
"固定表情";cls="radiobutton" };
radiobutton3={ dr=1;bottom=125;right=102;left=32;dt=1;top=104;z=4;text=
"固定内容";cls="radiobutton" };
static6={ dr=1;bottom=93;text=
"static6";left=28;dt=1;top=91;z=21;right=368;transparent=1;edge=1;cls="static" };
publishBtn={ bottom=295;right=360;left=243;top=257;z=23;text=
"看看发表什么";cls="button" };
fixedContentTxt={ dr=1;bottom=152;right=366;left=35;dt=1;top=131;z=19;edge=1;cls=
"edit" };
static8={ dr=1;bottom=164;text=
"static8";left=28;dt=1;top=162;z=22;right=369;transparent=1;edge=1;cls="static" };
checkbox2={ dr=1;bottom=70;right=201;left=145;dt=1;top=53;z=11;text=
"稀饭";cls="checkbox" };
static5={ dr=1;bottom=47;text=
"个";left=301;dt=1;top=29;z=9;right=349;transparent=1;cls="static" };
browseBtn={ dr=1;bottom=226;right=372;left=316;dt=1;top=198;z=20;text=
"浏览...";cls="button" };
browsePath={ dr=1;bottom=225;right=310;left=38;dt=1;top=203;z=18;edge=1;cls=
"edit" };
checkbox7={ dr=1;bottom=88;right=267;left=217;dt=1;top=72;z=16;text=
"汗";cls="checkbox" };
checkbox6={ dr=1;bottom=88;right=195;left=145;dt=1;top=72;z=15;text=
"难过";cls="checkbox" };
checkbox5={ dr=1;bottom=88;right=133;left=83;dt=1;top=72;z=14;text=
"无语";cls="checkbox" };
checkbox4={ dr=1;bottom=68;right=325;left=283;dt=1;top=53;z=13;text=
"吐";cls="checkbox" };
combobox={ dr=1;bottom=49;text=
"combobox3";left=250;dt=1;
items={
"5";"8";"10";"12";"15";"20";"25";"30" };right=291;z=8;top=29;mode="dropdown";edge=1;cls="combobox" };
checkbox8={ dr=1;bottom=88;right=333;left=283;dt=1;top=72;z=17;text=
"搞笑";cls="checkbox" };
radiobutton5={ dr=1;bottom=197;right=132;left=36;dt=1;top=178;z=6;text=
"随机导入内容";cls="radiobutton" };
radiobutton4={ dr=1;bottom=124;right=255;left=122;dt=1;top=104;z=5;text=
"固定内容+随机表情";cls="radiobutton" };
checkbox1={ dr=1;bottom=70;right=134;left=83;dt=1;top=53;z=10;text=
"赞";cls="checkbox" };
groupbox4={ dr=1;bottom=238;right=380;left=14;dt=1;top=10;text=
"设置发表内容";z=1;edge=1;cls="groupbox" };
radiobutton6={ dr=1;bottom=196;right=295;left=152;dt=1;top=178;z=7;text=
"随机导入内容+随机表情";cls="radiobutton" };
radiobutton1={ dr=1;bottom=48;right=100;left=30;dt=1;top=29;z=2;text=
"随机表情";cls="radiobutton" };
checkbox3={ dr=1;bottom=67;right=261;left=217;dt=1;top=53;z=12;text=
"愤怒";cls="checkbox" }
)
/*}}*/

import fsys.dlg;

mainForm.radiobutton1.checked=
true;
mainForm.combobox.selText=
"5";

//导入文本文件为tab
var importTxtTab=function(path){
   
if(!io.exist(path)){
        
error("请指定有效的路径",2)
        
return ;
    }
   
   
var str=string.load(path);
   
if(str){
        
var txtTab=string.split(str,'<\r\n>');
        
return txtTab;
    }   
}

//随机表情
var expressionTab={"[赞]";"[稀饭]";"[愤怒]";"[吐]";"[无语]";"[难过]";"[汗]";"[搞笑]"}
var randExpression=function(){
   
var count=mainForm.combobox.text;
   
var expression="";
   
for(i=1;tonumber(count);1){
        expression+=expressionTab[math.random(1, 8)]
    }
   
return expression;
}

//固定表情
var fixedExpression=function(){
   
var expression="";
   
var num=0;
   
var count=mainForm.combobox.selText;
   
while(num<=tonumber(count)){
        
var m=0
        
for(i=1;8;1){
            
if(mainForm["checkbox"++i].checked){
                expression+=expressionTab[ i ]
                num++;
               
if(num>tonumber(count)){
                    
return expression;
                }
            }
else {
                m++;
            }
            
            
//没有选定表情
            if(m=8){
               
return "";
            }
        }
    }   
}

//固定内容
var fixedContent=function(){
   
return mainForm.fixedContentTxt.text;
}

//固定内容加随机表情
var fixedContentAndRandExpression=function(){
   
return fixedContent()++randExpression();
}

//导入内容随机
var importContentRand=function(){
   
var importContentTab=importTxtTab(mainForm.browsePath.text)
   
if(#importContentTab){
        
return importContentTab[math.random(1, #importContentTab)];
    }
   
return "";  
}

//导入内容随机加随机表情
var importContentRandAandRandExpression=function(){
   
return importContentRand()++randExpression();
}

//发表内容函数表
var contentTab={
    randExpression;
    fixedExpression;
    fixedContent;
    fixedContentAndRandExpression;
    importContentRand;
    importContentRandAandRandExpression
}

//获取要发表的内容
var getPublicationContent=function(){
   
for(i=1;6;1){
        
if(mainForm["radiobutton"+i].checked){
            
return contentTab[ i ]();     
        }
    }   
}

mainForm.publishBtn.oncommand =
function(id,event){
   
var publicationContent=getPublicationContent()
    mainForm.msgbox(publicationContent)
}

mainForm.browseBtn.oncommand =
function(id,event){
   
var txtPath=fsys.dlg.open("文本文件|*.txt","请选择要导入的文件","\",mainForm);
   
if(txtPath){
        mainForm.browsePath.text=txtPath;
    }   
}
mainForm.show()
//进入消息循环
win.loopMessage();
  

评分

参与人数 1银币 +50 收起 理由
coder + 50 赞一个!

查看全部评分

小时候,幸福是一件东西,拥有就是幸福; 长大了,幸福是一个目标,达到就是幸福; 成熟后,发现幸福原来是一种心态,领悟就是幸福.
回复

使用道具 举报

117

主题

1237

帖子

6592

积分

六级会员

Rank: 9Rank: 9Rank: 9

积分
6592
发表于 2012-10-23 11:09:04 | 显示全部楼层

感谢分享

感谢分享
回复

使用道具 举报

43

主题

679

帖子

3805

积分

版主

Rank: 7Rank: 7Rank: 7

积分
3805
发表于 2012-10-23 11:26:50 | 显示全部楼层

我也来凑凑热闹 [hr] [align=left][font=新宋体]io.open() [/font] [color=#0000ff][font=新宋

我也来凑凑热闹


io.open()

var 条件 = 2;
处理条件1 = function(){
    io.print(
"a1执行了")
}
处理条件2 =
function(){
    io.print("a2执行了")  
}

//条件语句写法
if( 条件 == 1 ){
    处理条件1()
}
elseif( 条件 == 2 ){
    处理条件2()
}

//表驱动法
var 表 = {
    [1] = 处理条件1;
    [2] = 处理条件2;
}
表[条件]();

/*
如果有成千上万个不同的条件,
那你避免写成千上万个条件语句的做法,就是使用表驱动法,
使用表驱动法只要判断一次,可扩展性好,速度更快。

如果执行频率不多,条件也不多的代码,没有必要使用表驱动法,
那是把本来简单的事搞复杂,代码可读性永远是最重要的。
*/

回复

使用道具 举报

117

主题

1237

帖子

6592

积分

六级会员

Rank: 9Rank: 9Rank: 9

积分
6592
发表于 2012-10-23 11:30:56 | 显示全部楼层

[quote][size=2][color=#999999]编程 发表于 2012-10-23 11:26[/color] [url=forum.php?mod

编程 发表于 2012-10-23 11:26
我也来凑凑热闹


io.open()

简单明了 很不错
我是菜鸟...
回复

使用道具 举报

39

主题

195

帖子

1269

积分

四级会员

Rank: 6Rank: 6

积分
1269
发表于 2012-10-23 16:27:00 | 显示全部楼层

[quote][size=2][color=#999999]编程 发表于 2012-10-23 11:26[/color] [url=forum.php?mod

编程 发表于 2012-10-23 11:26
我也来凑凑热闹


io.open()

学习了!
回复

使用道具 举报

48

主题

593

帖子

3336

积分

五级会员

Rank: 8Rank: 8

积分
3336
发表于 2012-10-23 18:33:30 | 显示全部楼层

不错 多谢分享{:3_59:}

不错 多谢分享
回复

使用道具 举报

9

主题

79

帖子

582

积分

三级会员

Rank: 4

积分
582
发表于 2012-10-24 09:21:42 | 显示全部楼层

简单直观。明了。易懂。呵呵。

简单直观。明了。易懂。呵呵。
回复

使用道具 举报

14

主题

56

帖子

525

积分

培训班

积分
525
发表于 2012-10-24 10:34:09 | 显示全部楼层

发一个网上通俗的表驱动法文章(参考代码非AAU,不过一看就明白) 驱动表不是什么高深的东西,在《代码大全2》中有详细的讲解。 看一个简单的例子:

发一个网上通俗的表驱动法文章(参考代码非AAU,不过一看就明白)
驱动表不是什么高深的东西,在《代码大全2》中有详细的讲解。

    看一个简单的例子:
   
    2012过去了,仅存的人类从事原始的生产劳作,以集体为单位。很不幸2013年人类生产食物的总和有限,不得不根据对象的

特点进行食物的分配。最初的规则如下:

    20岁以上的男人,每人分配100斤食物
   
    20岁以下的男人,每人分配80斤食物
  
    20岁以上的女人,每人分配80斤食物

    20岁以下的女人,每人分配60斤食物

    于是你写了如下的代码

    int getFood(bool isMan,bool ageMoreThan20)
    {
        if(isMan)
        {
                if( ageMoreThan20)
                {
                        return 100;
                }
                else
                {
                        return 80;
                }
        }
        else
        {
                if( ageMoreThan20)
                {
                        return 80;
                }
                else
                {
                        return 60;
                }
        }
     }   

     于是你很满意,因为你圆满完成了人类食物的分配工作,保证了大家尽块可能吃饱。但是突然,一群大胖子找到了

把你狠揍你一顿,最后你搞明白了,原来这样的分配方式让他们吃不饱。你很自责与愧疚,于是要改这个算法,增加了

这样的规则:

     20岁以上的男胖子120斤
     20岁以下的男胖子100斤
     20岁以上的女胖子100斤
     20岁以下的女胖子80斤

代码就变成了这样
   
    int getFood(bool isMan,bool ageMoreThan20,bool isFatMan)
    {
        if(isMan)
        {
                if( ageMoreThan20)
                {
                        if(isFatMan)
                        {
                                return 120;
                        }
                        else
                        {
                                return 100;
                        }
                }
                else
                {
                        if(isFatMan)
                        {
                                return 100;
                        }
                        else
                        {
                                return 80;
                        }
                }
        }
        else
        {
                if( ageMoreThan20)
                {
                        if(isFatMan)
                        {
                                return 100;
                        }
                        else
                        {
                                return 80;
                        }
                }
                else
                {
                        if(isFatMan)
                        {
                                return 80;
                        }
                        else
                        {
                                return 60;
                        }
                }
        }
     }  
      

写完这段代码,你揉着太阳穴,并感到莫名的紧张和不安,为啥呢?你看到太多的if else;看到太多的代码;同时你想到

了代码的可读性、可维护性、可扩展性。“擦,下次再增加一个判断因子的话。。。。”

代码大全告诉我们,当遇到太多if else,已经深成的嵌套的时候,你应该告诉自己,coder就应该对自己狠一点,把现有的

的代码删除吧,用驱动表吧,这才能拯救人类。


驱动表:其实就是一个多维数组,他的维数由变项的数量决定,如果变项为3,则是一个3维数组,每个元素值代表着3种变项

的一种具体的组合对应的值;这样我们就把对if else的维护,变成了对数组的维护。代码可以是这样。


int val[2][2][2];

该数组的一维代表性别,0为男人,1为女人
该数组的二维代表年龄,0为大于20,1小于20岁
该数组的三维代表是否是胖子,0为是胖子,1代表不是胖子

所以val[0][0][0]=120表示20岁以上的男胖子分配120斤食物。



对这个数组的8个值进行初始化

int getFood(bool isMan,bool ageMoreThan20,bool isFatMan)
{
        return val[isMan][ageMoreThan20][isFatMan];
}

驱动表的优点在于:

1,维护数组比维护if else容易
2, 代码简洁
3,性能高(直接是偏移地址的运算)

驱动表实际是一个值的存取和访问,这个值可以是一个具体的值、一个处理方法的引用、一个对象。而对这个值的访问

可以是直接寻址,如例子所示、也可以是索引(key值为字符串)、也可以是阶梯形式。

点评

如果说表驱动法有什么不适合使用的场景,个人认为就是你举的这个例子。  发表于 2012-10-24 10:51
这篇文章有点误导,把简单的事搞的复杂了,表驱动法没必要用的这么夸张  发表于 2012-10-24 10:49
回复

使用道具 举报

0

主题

42

帖子

363

积分

二级会员

Rank: 3Rank: 3

积分
363
发表于 2012-10-24 10:43:35 | 显示全部楼层

超级版主 感谢分享

超级版主
感谢分享
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册会员

本版积分规则

手机版|未经许可严禁引用或转载本站文章|站长邮箱|aardio.com|aardio官方社区 ( 皖ICP备09012014号 )

GMT+8, 2018-11-15 18:28 , Processed in 0.078128 second(s), 23 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表