免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1804 | 回复: 1
打印 上一主题 下一主题

[Altorithm] 有限状态机(FSM)实现字符串分解 (ZT) [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-12-22 08:51 |只看该作者 |倒序浏览
VC++2008下写的,因此用到了CString,同时Potlet是我自己写了一个容器,真的使用的时候可以换成STL容器例如vector<CString>。
改程序读取一个source字符串,里面包含若干逗号分隔符,希望自动分解source字串,得到若干子串,放置到Potlet中,虽然功能非常简单,但 是依然包含了很多很多情况,比如多个逗号,逗号在source头部,逗号在source尾部。。。如果用传统的方法编写程序,将会变得很复杂,并且容易出 错。传统算法的流程图:

如果采用状态机的思想来实现,则会变得非常简单:


其中NORMAL表示读到的是一个正常字符,COMA表示读到的是一个逗号,ZERO表示读到的是'\0'字符,这也是最终状态。程序仅需列举出所有的状态(state)和路径(path),并且进行合适地处理就可以了。
代码如下:

//代码开始
#define NORMAL 0
#define COMA 1
#define ZERO 2

int getState(char c)
{
    if(c=='\0')
        return ZERO;
    if(c==',')
        return    COMA;
    return NORMAL;  
}

/*
we push subStr to Potlet and clear subStr only when the state change from NORMAL to COMA(path B) or ZERO(path E)
*/
Potlet getPotletString(CString source)
{
    Potlet potlet;//the potlet to save subStrs
    //if source is null,return a potlet contains nothing
    if (len<=0)
        return potlet;
       
    int state;//show the state
    char chr[]=source;//get a char[] type source,without extra data
    CString subStr="";//buffer of sub String

    state=getState(chr[0]);//get initial state,of cause the chr is not null,so we can use chr[0]
    int i=0;//show the location in chr
   
    //FSM runs here
    while(state!= ZERO)
    {
        switch(state)
        {
        //it's NORMAL
        case NORMAL:
            subStr+=chr[i];//add chr[i] to subStr
            //move
            i++;
            //get next state
            state=getState(chr[i]);
            switch(state)
            {
            //path A
            case NORMAL:
                //do nothing
                break;
            //path B
            case COMA:
                potlet.push_back(subStr+'\0');
                subStr="";
                break;
            //path E
            case ZERO:
                potlet.push_back(subStr+'\0');
                break;
            }
            break;
       
        //it's a comma
        case COMA:
            //move
            i++;
            //get next state
            state=getState(chr[i]);
            switch(state)
            {
                //path C
                case NORMAL:
                //do nothing
                break;
                //path D
                case COMA:
                //do nothing
                break;
                //path F
                case ZERO:
                //do nothing
                break;
            }
           
            break;
        }//end switch
    }
    //the state is ZERO
    return potlet;
}
//代码结束

论坛徽章:
0
2 [报告]
发表于 2012-05-10 16:11 |只看该作者
转载请注明出处!原创链接如下:
http://hi.baidu.com/albertdiao/b ... b0d53b5882dde3.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP