今天休息的时候看到一个关于单词统计的小题目:
统计一段由字符和和空格组成的字符串中有多少个单词
题目一看觉得很简单,无非是遍历字符串,然后根据字母是不是空格之类的来统计单词的个数。博主用了一个状态机来做这件事,我觉得颇有新意,所以就记下心来了。后面的留言有人觉得博主这是把简单问题复杂化,其实我觉得不然。最近在看《设计模式精解》,开篇作者提出的观点我就觉得非常好:需求总是在发生变化的,我们必须让我们写出的代码能够适应变化,而不是为预防变化而费尽必力。一语中的,想起大三的时候刚参与实习的时候,那个时候认为需求一旦定下来了就没有理由变,从而把责任怪罪到定义需求的人上面去,其实是多么狭隘。同样,我觉得两种做法的区别就是,后者更能适应需求的变化。想想,如果字符串除了空格和字符,还加上了各种符号啊之类的,前者的代码写起来就不那么好看了,从而也不好维护了。
下面是我写的两种实现方法:
#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;
}
相比之下,其实写第一种实现方法的时候花了我比较多的时间,因为我很害怕出错,而第二种实现方法很规则,只要照着状态机的转移图写就行了,不容易出错,下面是我画的状态图:
单词数增加的途径只有两个:从AlphaState->SpaceState,或者是从AlphaState到字符串结束。当需求发生变化时,我们或者添加新的状态,或者对状态的转移条件做一定的修改,很方便,而且不容易出错。
- 大小: 21.4 KB
分享到:
相关推荐
只有一行,如果在文章中找到给定单词则输出两个整数,两个整数之间用一个空格隔开,分别是单词在文章中出现的次数和第一次出现的位置(即在文章中第一次出现时,单词首字母在文章中的位置,位置从0开始);如果单词...
在这个问题中,我们很可能需要编写一个程序,该程序读取一系列输入文件(如1.in、2.in等),统计其中的单词数量,并将结果输出到对应的输出文件(如1.out、2.out等)。这个任务通常在编程竞赛或数据处理场景中出现,...
标题 "统计单词数 1" 是一个关于编程算法的题目,目标是统计输入段落中所有不同单词出现的次数,并按出现顺序输出。这个任务主要考察的是字符串处理和哈希表(或字典)的应用。 描述中提到,输入的数据是一个包含...
给定一个句子(只包含字母和空格), 将句子中的单词位置反转,单词用空格分割, 单词之间只有一个空格,前后没有空格。 比如: (1) “hello xiao mi”-> “mi xiao hello” 输入描述: 输入数据有多组,每组占一行...
实现统计一段文章的每个单词的个数 其中CountDemo使用STL中的Map来实现的 CountDemo2是用一般语言实现,没有用到STL实现的; MapCount是用STL中的Vector和Map共同实现的 此题目是学习STL中的Map和Vector必练的经典...
这个程序虽然没有完全实现找出只出现一次的单词的功能,但提供了基础的单词统计和提取步骤。要完成题目要求,需要额外实现对单词计数的跟踪和只出现一次的单词的筛选。这通常涉及使用哈希表或数组作为数据结构,以更...
总的来说,这段代码实现了一个简单的文本分析器,可以统计一行文本中单词的个数以及每个英文字母的出现次数。然而,代码中有一部分(去除重复字母)可能不是题目要求的功能,而是额外的逻辑。如果仅需统计单词数量和...
2. **计数算法**:设计一个有效的算法来统计单词数,可以是基于字符遍历,也可以使用数据结构如哈希表来优化查找过程。 3. **边界条件**:考虑特殊输入,如空字符串、只有一个单词的字符串、单词之间有多个空格等...
一篇英文文章存储在一个文本文件中,然后分别基于线性表、二叉排序树和哈希表不同的存储结构,完成单词词频的统计和单词的检索功能。同时计算不同检索策略下的平均查找长度ASL,通过比较ASL的大小,对不同检索策略的...
标题中的“一个简单的单词处理程序”表明这是一个基本的文本处理应用程序,可能用于查找、替换、统计或操作文本文件中的特定单词。在这个上下文中,“单词”可能指的是文本文件中的单独文字或者由空格、标点符号分隔...
在这个编程任务中,我们需要处理一个名为`input.txt`的文本文件,从中提取英文单词,并将它们按照字典顺序排列。最终结果将被保存到`output.txt`文件中,每个单词占一行,单词后面紧跟着其在文件中出现的次数,两者...
标题中的"不同单词个数统计 1"是一个关于算法的问题,描述中提到的任务是编写一个程序,接收一个句子作为输入,然后计算其中不同单词的数量。这个任务涉及到的主要知识点包括字符串处理、算法设计以及数据结构。 ...
这是一个基础的字符串处理问题,要求统计给定字符串中各个字符出现的次数。在编程中,我们通常使用哈希表(Hash Table)或字典(Dictionary)数据结构来高效地实现。遍历字符串,对每个字符进行计数,最后返回包含每...
英文文章单词数统计是C++课程设计题目中的一个重要方面。该题目要求读取一个英文文章的txt文件,并统计单词的个数、关键字(the和and)的个数、空格的个数、标点符号的个数。该题目考察了C++语言的文件输入、字符串...
提示1:文章需要经过若干次处理 大小写处理 替换特殊符号处理 分隔单词处理 提示2:利用hashtable进行统计 单词作为key 个数作为value foreach string i in strword if ht Contains i ht Add i 1 ; else ht[i]...
包括源代码 课程设计报告 可执行文件 该程序由个人完成,希望多多支持,下载后评个分,注意,评价...2、程序的界面布局参考如下图,在第一个单行文本框输入一单词,点击“计算”按钮,按照以上算法计算出该单词的值。
在C语言中,查找一个已知字符串中的最长单词是一项常见的编程任务,这涉及到字符串处理、指针操作以及循环控制等基础知识。在这个问题中,我们假设输入的字符串仅包含字母和空格,空格用于分隔不同的单词。接下来,...
for (String word : line.split("\\s+")) { // 分割单词,\\s+匹配一个或多个空白字符 word = word.toLowerCase().replaceAll("\\p{Punct}", ""); // 预处理 if (word.isEmpty()) continue; // 跳过空单词 ...
根据给定的文件标题、描述以及部分源代码来看,本程序旨在完成两个功能:一是统计一个字符串中单词的数量;二是将字符串中所有连续出现的数字提取出来并存储到一个一维数组中。 #### 2. 分析源代码 首先我们来分析...