您的位置:首页 > 其它

全是套路——字符串通配符

2016-07-06 17:47 246 查看
华为OJ的题:

问题描述:在计算机中,通配符一种特殊语法,广泛应用于文件搜索、数据库、正则表达式等领域。现要求各位实现字符串通配符的算法。
要求:
实现如下2个通配符:
*:匹配0个或以上的字符(字符由英文字母和数字0-9组成,不区分大小写。下同)
?:匹配1个字符

输入:
通配符表达式;
一组字符串。

输出:
返回匹配的结果,正确输出true,错误输出false

在OJ里面是初级题。最近脑子很笨,反应不过来。也是在网上看了思想之后才编出来的。

具体思想:

1.由于*可以代替任意字符,所以*先要忽略

2.?可以代替一个字符,所以将它考虑到当中

3.以*为分隔符来分割字符串,现在字符串是一系列的字符。如果第一个字符跟整体匹配上了,下一个字符接着上一个匹配的末尾继续匹配,以此类推,都匹配成功就算匹配成功。

4.字符串的匹配因为涉及到?,不能直接用string的find。所以用kmp算法。

KMP具体来说,就是在原字符串中找到第一个与匹配字符串相同的字母,然后依次匹配若成功则返回,若失败,则记录失败的位置,下次从失败的位置开始匹配。这样可以提高效率。

注:对于?匹配其实没有那么麻烦,只有在if语句中加上一个||就可以了如果匹配字符串中的那个位是?就默认匹配成功。

上代码:

#include <stdio.h>
#include <iostream>
#include <stack>
#include <string>
#include <vector>

using namespace std;

char daxie(char c)
{
if (c >= 'A'&&c <= 'Z')
{
c = c - 'A' + 'a';
}
return c;
}

int pipei(string S, string T)
{
int index = 0;
for (int i = index; i < S.size(); i++)
{
if (S[i] == T[0]||T[0]=='?')
{
int k;
for (k = 0; k < T.size() && k+i <S.size() ; k++)
{
if (S[k+i] == T[k]||T[k]=='?')
{

}
else
{
index = k + i;
break;
}
}
if (k == T.size() )
{
return i;
}
}
}
return -1;
}

int main()
{
string str1, str2;
while (cin >> str1>>str2)
{
for (int i = 0; i < str1.size(); i++)
{
str1[i] = daxie(str1[i]);
}
for (int i = 0; i < str2.size(); i++)
{
str2[i] = daxie(str2[i]);
}
vector<string> a;
int pos = -1;
while ((pos = str1.find('*')) != string::npos)
{
a.push_back(str1.substr(0, pos));
str1 = str1.erase(0, pos + 1);
}
a.push_back(str1);
for (int i = 0; i < a.size(); i++)
{
if (a[i] == "")
{
a.erase(a.begin() + i, a.begin() + i + 1);
}
}
int i;
for (i = 0; i < a.size(); i++)
{
int pos = -1;
if ((pos = pipei(str2, a[i])) < 0)
{
cout << "false" << endl;
break;
}
else
{
str2 = str2.erase(0, pos + a[i].size());
}
}
if (i == a.size())
{
cout << "true" << endl;
}

int kk = 0;
}

return 0;

}


注意:此代码是有些问题的。比如你输入*,按道理是都能匹配的,但是有字符串分割没有成功,所以会失败,但是就不更改了。

还有一个问题,虽然华为的系统没有检测,但是还是不能忽略的。

*只能代表数字和字母,并不能匹配除这以外的。(可能是华为的测试样例也没有考虑吧)

所以如果输入*.* 和...也会匹配成功,这是不严谨的。所以说匹配的时候,在跳过的那几个串中要检测有没有*不能替代的字符,如果算不匹配。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: