在前篇文章中提出的问题,后来在那本经典教程《C++ Primer》的第六章里有相关的解决方案。虽然之前早闻这是本好书,并下载了电子版,比较随意的看了几个章节,没完全看完,毕竟是本很厚的书,借这次机会认真的看了第六章,感觉真的写的不错,即使不是初学者,一样有很多地方值得体会。代码写的很优美,读着就是种享受,作者的思维很周密。作者也在文中写到:“后缀问题很难完全解决,但是完美的实现会显著改善我们查询单词集合的质量和大小”,他说的后缀问题就是我上次说的语法问题。下面就是相关的解决方法:
符号问题的处理:
void filtrate_word(string& word)//处理字符串中的标点符号
{
static string filter( "/",.;:!?)(///" );//要过滤的标点符号集,也可以自己加如其他的符号
string::size_type pos = 0;
// 对于找到的符合过滤的符号, 将其删除
while (( pos = word.find_first_of( filter, pos )) != string::npos )
{
word.erase(pos,1);
}
}
顺便把单词中的大小写也统一一下,很简单:
void strip_cap( string& word)//将单词中的大写字母转化成小写字母
{
static string caps( "ABCDEFGHIJKLMNOPQRSTUVWXYZ" );
string::size_type pos = 0;
while (( pos = word.find_first_of( caps, pos )) != string::npos )
{
word[ pos ] = tolower( word[pos] );
}
}
两处处理都用到string类的函数find_first_of(),有几个重载,它是查找与被搜索字符串中任意一个字符相匹配的第一次出现,并返回它的索引位置。
语法问题的处理,书中是分成几类来处理,处理分s、ed、ly、ing等后缀处理,如可以定义成suffix_s();suffix_ed(); suffix_ly; suffix_ing()等函数,而s的后缀有几种情况来处理,如果单词以ies 结尾如babies 和cries 则我们需要用y 代替ies。
void suffix_s(string& word)//后缀s的处理
{
string::size_type pos3 = word.size()-3;
string ies( "ies" );
if ( ! word.compare( pos3, 3, ies ))
word.replace( pos3, 3, 1, 'y' );
//其他情况处理
}
void suffix_word(string& word )//后缀的处理比如ed ing ly 等
{
//后缀s的处理
if ( word[ word.size ()-1 ] == 's' )
suffix_s( word );
// 其他处理
}
感觉这样处理后缀,容易考虑不周全,会考虑不到一些特殊情况,作者也是这样认为。如果要有比较好的效果估计要写很多的后缀处理函数。