一个小题目(单词统计)

今天休息的时候看到一个关于单词统计的小题目:

[b]统计一段由字符和和空格组成的字符串中有多少个单词[/b]

题目一看觉得很简单,无非是遍历字符串,然后根据字母是不是空格之类的来统计单词的个数。博主用了一个状态机来做这件事,我觉得颇有新意,所以就记下心来了。后面的留言有人觉得博主这是把简单问题复杂化,其实我觉得不然。最近在看《设计模式精解》,开篇作者提出的观点我就觉得非常好:需求总是在发生变化的,我们必须让我们写出的代码能够适应变化,而不是为预防变化而费尽必力。一语中的,想起大三的时候刚参与实习的时候,那个时候认为需求一旦定下来了就没有理由变,从而把责任怪罪到定义需求的人上面去,其实是多么狭隘。同样,我觉得两种做法的区别就是,后者更能适应需求的变化。想想,如果字符串除了空格和字符,还加上了各种符号啊之类的,前者的代码写起来就不那么好看了,从而也不好维护了。

下面是我写的两种实现方法:

#include<iostream>
using namespace std;

/** description:
** given a string of alpha and spaces,
** return how many words are there in the string
** Words are seperated by space(s)
**/

int wordsCount( const char* str )
{
if( str == NULL )
return 0;
int count = 0;
char cur;
while( cur = *str )
{
if( cur == ' ' )
while( *(++str)!='\0' && *str==' ' );
else
{
count++;
while( *(++str)!='\0' && *str!=' ' );
}
}
return count;
}

/** now let's try another solution with state machine */
int wordsCountSM( const char* str )
{
enum STATE { InitState, SpaceState, AlphaState };
int count = 0;
char cur;
STATE state = InitState;
while( cur = *str++ )
{
switch(state)
{
case InitState:
if( cur == ' ' )
state = SpaceState;
else
state = AlphaState;
break;
case SpaceState:
if( cur != ' ' )
state = AlphaState;
break;
case AlphaState:
if( cur == ' ' )
{
state = SpaceState;
count ++;
}
break;
default:
break;
}
}
if ( state == AlphaState )
count++;
return count;
}


int main()
{
char* test1 = "this is a normal string";
char* test2 = " this is a abnormal string";
char* test3 = "this is an abnormal string ";
char* test4 = " this is an abnormal string ";
char* tests[4] = { test1, test2, test3, test4 };
for( int i=0; i<4; i++ )
{
cout<<wordsCount(tests[i])<<' '<<wordsCountSM(tests[i])<<endl;
}
return 0;
}


相比之下,其实写第一种实现方法的时候花了我比较多的时间,因为我很害怕出错,而第二种实现方法很规则,只要照着状态机的转移图写就行了,不容易出错,下面是我画的状态图:

[img]http://dl.iteye.com/upload/attachment/0072/3215/fd35b9cf-ffe4-30ea-828b-5581ff672fe8.jpg[/img]
单词数增加的途径只有两个:从AlphaState->SpaceState,或者是从AlphaState到字符串结束。当需求发生变化时,我们或者添加新的状态,或者对状态的转移条件做一定的修改,很方便,而且不容易出错。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值