华为机试HJ71:字符串通配符
Posted 翟天保Steven
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了华为机试HJ71:字符串通配符相关的知识,希望对你有一定的参考价值。
作者:Steven
版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处
题目描述:
问题描述:在计算机中,通配符一种特殊语法,广泛应用于文件搜索、数据库、正则表达式等领域。现要求各位实现字符串通配符的算法。
要求:
实现如下2个通配符:
*:匹配0个或以上的字符(字符由英文字母,数字0-9和 '.' 组成,下同)
?:匹配1个字符
注意:匹配时不区分大小写。
输入:
通配符表达式;
一组字符串。
输出:
返回不区分大小写的匹配结果,匹配成功输出true,匹配失败输出false
本题含有多组样例输入!
输入描述:
先输入一个带有通配符的字符串,再输入一个需要匹配的字符串
输出描述:
返回不区分大小写的匹配结果,匹配成功输出true,匹配失败输出false
示例:
输入:
te?t*.* txt12.xls
输出:
false
解题思路:
本题用动态规划解比递归要方便,而且速度也快些。输入两个字符串,按照各自的尺寸建立二维数组,并定义(0,0)点为true,其他默认为false;每一行首值的取值,取决于上一行首值和通配符字符串s1该位置字符是否为'*',即当s2无字符时,s1只有首字符为'*'才能与其匹配;之后继续填充,首行数值均为false,即s1无字符时,无法进行匹配;从第二行第二列开始,一行行填充,若s1对应位置的字符为'*',则该行的数值由其同行前列和同列前行决定,若其同列前行为true,表明之前的匹配均合理,再考虑到*可以匹配0个字符,所以该位置可以true,但注意,还要判断s2字符是否合理;若该行对应s1字符为正常字母数字,则进行正常比对,若同s2字符一致(不区分大小写),且其前列前行为true,则当前也为true,这是当前已经成功匹配的字符串位置;若s1字符为'?',则只需判断s2字符是否合理,若合理且前列前行也为true,当前也为true。
动态规划的二维表遍历完,最终匹配结果就是v[m][n]。解题完毕。
测试代码:
#include <iostream>
#include <string>
#include <vector>
using namespace std;
// 判断字符是否符合要求
bool isOk(char c)
{
return (isalpha(c)||isalnum(c)||c=='.');
}
bool Match(string s1,string s2)
{
int m = s1.size();
int n = s2.size();
vector<vector<bool>> v(m+1,vector<bool>(n+1,false));
v[0][0] = true;
for(int i=1;i<=m;++i)
{
v[i][0] = v[i-1][0]&&(s1[i-1]=='*');
for(int j=1;j<=n;++j)
{
if(s1[i-1]=='*'){
if(isOk(s2[j-1]))
{
v[i][j] = v[i-1][j]||v[i][j-1];
}
}else{
if(tolower(s1[i-1])==tolower(s2[j-1]))
v[i][j] = v[i-1][j-1];
if(s1[i-1]=='?' && isOk(s2[j-1]))
v[i][j] = v[i-1][j-1];
}
}
}
return v[m][n];
}
int main(void)
{
string s1,s2;
while(cin>>s1>>s2)
{
if(Match(s1, s2)){
cout << "true" << endl;
}else{
cout << "false" << endl;
}
}
return 0;
}
以上是关于华为机试HJ71:字符串通配符的主要内容,如果未能解决你的问题,请参考以下文章