全是套路——字符串通配符
2016-07-06 17:47
246 查看
华为OJ的题:
问题描述:在计算机中,通配符一种特殊语法,广泛应用于文件搜索、数据库、正则表达式等领域。现要求各位实现字符串通配符的算法。
要求:
实现如下2个通配符:
*:匹配0个或以上的字符(字符由英文字母和数字0-9组成,不区分大小写。下同)
?:匹配1个字符
输入:
通配符表达式;
一组字符串。
输出:
返回匹配的结果,正确输出true,错误输出false
在OJ里面是初级题。最近脑子很笨,反应不过来。也是在网上看了思想之后才编出来的。
具体思想:
1.由于*可以代替任意字符,所以*先要忽略
2.?可以代替一个字符,所以将它考虑到当中
3.以*为分隔符来分割字符串,现在字符串是一系列的字符。如果第一个字符跟整体匹配上了,下一个字符接着上一个匹配的末尾继续匹配,以此类推,都匹配成功就算匹配成功。
4.字符串的匹配因为涉及到?,不能直接用string的find。所以用kmp算法。
KMP具体来说,就是在原字符串中找到第一个与匹配字符串相同的字母,然后依次匹配若成功则返回,若失败,则记录失败的位置,下次从失败的位置开始匹配。这样可以提高效率。
注:对于?匹配其实没有那么麻烦,只有在if语句中加上一个||就可以了如果匹配字符串中的那个位是?就默认匹配成功。
上代码:
注意:此代码是有些问题的。比如你输入*,按道理是都能匹配的,但是有字符串分割没有成功,所以会失败,但是就不更改了。
还有一个问题,虽然华为的系统没有检测,但是还是不能忽略的。
*只能代表数字和字母,并不能匹配除这以外的。(可能是华为的测试样例也没有考虑吧)
所以如果输入*.* 和...也会匹配成功,这是不严谨的。所以说匹配的时候,在跳过的那几个串中要检测有没有*不能替代的字符,如果算不匹配。
问题描述:在计算机中,通配符一种特殊语法,广泛应用于文件搜索、数据库、正则表达式等领域。现要求各位实现字符串通配符的算法。
要求:
实现如下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; }
注意:此代码是有些问题的。比如你输入*,按道理是都能匹配的,但是有字符串分割没有成功,所以会失败,但是就不更改了。
还有一个问题,虽然华为的系统没有检测,但是还是不能忽略的。
*只能代表数字和字母,并不能匹配除这以外的。(可能是华为的测试样例也没有考虑吧)
所以如果输入*.* 和...也会匹配成功,这是不严谨的。所以说匹配的时候,在跳过的那几个串中要检测有没有*不能替代的字符,如果算不匹配。
相关文章推荐
- php页面的基本语法
- TSung测试XMPP协议--测试过程中出现问题
- Linux内核分析:中断和异常(1)
- JSON学习基础链接
- vs 查询项目代码总行数
- 静态代码扫描——FindBugs自定义规则入门
- Apple移动设备处理器指令集 armv6、armv7、armv7s及arm64
- oracle时间日期格式例子大全
- AIDL 绑定服务的遇到的问题
- 使用递归算法从给定树上任意几个节点将这几个节点的所有下级 和 上级返回出来
- 笔记十二:智能指针(二)
- 清除UIWebView的缓存
- 关于easyUI在子页面增加显示tabs的一个问题
- android 夜间模式设置
- Linux命令行
- 生活 网
- [高斯消元 线性基] BZOJ 4269 再见Xor
- IOS开发之----常用宏定义和讲解_IOS-Coding_新浪博客
- ORB原理与Opencv源码解析
- RecyclerView初步学习(一)