题目
在一篇英文文章中查找指定的人名,人名使用二十六个英文字母(可以是大写或小写)、空格以及两个通配符组成(?),通配符 “ * ” 表示零个或多个任意字母,通配符“?”表示一个任意字母。如:“J* Smi??” 可以匹配“John Smith” .
分析
假设文章内容使用pText指针表示,通配符字符串使用pName指针表示,要完成这样的匹配任务,是需要一个一个字符开始去匹配的:
- 当pName中的字符不是通配符时,直接与pText的值比较,若相等,则pName++,pText++再进行比较,若不等,则表明当前匹配失败,需要将pText后移一位然后再进行匹配;
- 当pName中的字符是通配符 * 时,当前有两种情况:一种是直接让pName所对应的值与pText++所对应的值比较,一种情况是直接让pName++与pText对应的值进行比较,这里显然是要使用递归方式的。
- 当pName中的通配符是 ? 时,直接忽略掉这次比较结果,让pName++和pText++,然后再进行比较。
一直按照上面的比较方式进行比较,直到pName所指值为’\0’或者pText所指值为’\0’结束即可。
说的那么复杂,实际匹配函数如下所示:
bool match(char *pText, char *pName){
if(*pName == '\0'){
p = pText;
return true;
}
if(*pText == '\0'){
if(*pName == '*' && *(pName+1) == '\0'){
p = pText;
return true;
}
else
return false;
}
if(*pName != '*' && *pName != '?'){
if(*pName == *pText)
return match(pText+1, pName+1);
else
return false;
} else {
if(*pName == '*')
return match(pText+1, pName) || match(pText, pName+1);
else
return match(pText+1, pName+1);
}
}
匹配函数完成过后,就需要真正完成扫描函数,若存在匹配则返回匹配过后的值,若不存在匹配,则不返回,匹配函数是针对已经给定位置的情况,那么扫描函数就是针对pText,一个字符一个字符开始扫描:
void scan(char* pszText, char* pszName){
if(NULL == pszText || NULL == pszName)
return ;
while(*pszText != '\0'){
if(*pszText == *pszName){
bool flag = match(pszText, pszName);
if(flag){
cout << "match string : ";
while(pszText != p){
cout << *pszText;
pszText++;
}
cout << endl;
}
} else{
pszText++;
}
}
}