AC自动机通配符匹配
来源:互联网 发布:数据库双机备份 编辑:程序博客网 时间:2024/05/19 05:32
原文链接:http://blog.csdn.net/waitfor_/article/details/18563709
在计算机(软件)技术中,通配符可用于代替字符。 通常地,星号“*”匹配0个或以上的字符,问号“?”匹配1个字符。(wiki百科)
今天做Leetcode上的一道题时不会做,网上查到了这么一种做法,当年打比赛的时候都没有碰到过。。。。
Leetcode Wildcard Matching
递归做法TLE
- class Solution {
- public:
- bool isMatch(const char *s, const char *p) {
- char cs = *s;
- char cp = *p;
- if(cp == '\0') {
- return cs == cp;
- } else if (cp == '?') {
- if (cs == '\0') return false;
- return isMatch(s + 1,p + 1);
- } else if (cp == '*') {
- const char *st = s;
- while(cp == '*'){
- p++;
- cp = *p;
- }
- for(; *st != '\0'; ++st) {
- if (isMatch(st, p)) return true;
- }
- return isMatch(st,p);
- } else if (cp != cs)
- return false;
- return isMatch(s + 1,p + 1);
- }
- };
非递归改改AC
- class Solution {
- public:
- bool isMatch(const char *s, const char *p) {
- // Start typing your C/C++ solution below
- // DO NOT write int main() function
- const char* star=NULL;
- const char* ss=s;
- while (*s){
- if ((*p=='?')||(*p==*s)){s++;p++;continue;}
- if (*p=='*'){star=p++; ss=s;continue;} //star可以更新,使用贪心法
- if (star){ p = star+1; s=++ss;continue;}
- return false;
- }
- while (*p=='*'){p++;}
- return !*p;
- }
- };
HDU 3901
关于AC自动机通配符匹配的相关知识请看点击打开链接
- #include<cstdio>
- #include<cstring>
- #include<vector>
- using namespace std;
- #define N 100005
- #define B 26
- int tree[N][B],size;
- vector<int> key[N];
- int cnt[N],tcnt;
- void build(char str[]){
- size=tcnt=0;
- memset(tree[0],0,sizeof(tree[0]));
- key[0].clear();
- int node=0;
- for(int i=0;!i||str[i-1];i++){
- if(str[i]=='?'||str[i]==0){
- if(node){
- key[node].push_back(i-1);
- node=0; tcnt++;
- }
- continue;
- }else{
- int c=str[i]-'a';
- if(!tree[node][c]){
- tree[node][c]=++size;
- memset(tree[size],0,sizeof(tree[size]));
- key[size].clear();
- }
- node=tree[node][c];
- }
- }
- }
- int que[N];
- int fail[N];
- void getfail(){
- int *s=que,*e=que;
- for(int i=0;i<B;i++){
- if(tree[0][i]){
- fail[tree[0][i]]=0;
- *e++=tree[0][i];
- }
- }
- while(s!=e){
- int p=*s++;
- for(int i=0;i<B;i++){
- if(tree[p][i]){
- int v=tree[p][i];
- *e++=v;
- fail[v]=tree[fail[p]][i];
- if(key[fail[v]].size()){
- key[v].insert(key[v].end(),
- key[fail[v]].begin(),key[fail[v]].end());
- }
- }else{
- tree[p][i]=tree[fail[p]][i];
- }
- }
- }
- }
- int find(char str[]){
- if(tcnt==0) return 0;
- int node=0;
- for(int i=0;str[i];i++){
- node=tree[node][str[i]-'a'];
- cnt[i] = 0;
- for(int j=0;j<key[node].size();j++){
- if(i>=key[node][j]){
- cnt[i-key[node][j]]++;
- if(cnt[i-key[node][j]]==tcnt) return i-key[node][j];
- }
- }
- }
- return -1;
- }
- char tmp[N];
- char src[N];
- char wild[N];
- bool match(int ls, int lp){
- int tl=0;
- for(int i=0;i<lp;i++) if(wild[i]!='*') tl++;
- if(tl>ls) return false;
- int s=-1;
- for(int i=0;i==0||src[i-1];i++){ //如果最左不是*需要从头开始匹配到第一个*
- if((src[i]!=0&&wild[i]=='?')||src[i]==wild[i]) continue;
- if(wild[i]=='*') s=i+1;
- else return false;
- break;
- }
- if(s==-1) return true;
- for(int i=ls-1,j=lp-1;;i--,j--){ //如果最右不是*需要从结尾开始倒着匹配到倒数第一个*
- if(i==-1&&j==-1) break;
- if(i==-1){
- if(wild[j]!='*') return false;
- break;
- }
- if(j==-1) return false;
- if(src[i]==wild[j]||wild[j]=='?'){
- src[ls=i] = wild[j] = 0;
- } else if(wild[j]=='*') break;
- else return false;
- }
- int ts=s-1;
- for(int i=1;i<lp-tl;i++){ //剩下的部分为*......*将其中每个**中间部分用AC自动机匹配即可
- if(wild[s]=='*'){s++;continue;}
- int len = 0;
- for(;wild[s]!='*'&&wild[s];s++){
- tmp[len]=wild[s];
- tmp[++len]=0;
- }
- s++;
- build(tmp);
- getfail(); //这两步构造AC自动机
- int pos=find(src+ts); //寻找最左边匹配位置
- if(pos==-1) return false;
- else{
- ts+=pos+len;
- if(ts>ls) return false;
- }
- }
- return true;
- }
- int main(){
- while(~scanf("%s", src)){
- scanf("%s", wild);
- puts(match(strlen(src), strlen(wild))?"YES":"NO");
- }
- }
0 0
- AC自动机通配符匹配
- AC自动机通配符匹配
- 字符串匹配-AC自动机
- AC自动机匹配
- 【AC自动机】地图匹配
- lintcode 通配符匹配 ac代码
- lintcode 通配符匹配 ac代码
- 多串匹配-AC自动机
- 多串匹配 AC自动机
- AC自动机(多模串匹配)
- 【AC自动机+DP】匹配(match)
- 字符串匹配之AC自动机
- 数据结构-字符串匹配AC自动机
- 32.3-5带有通配符的匹配(自动机)
- 多模式匹配--AC自动机算法
- AC自动机(多模式匹配)
- AC自动机 多字符串匹配 code
- AC自动机(矩阵匹配)uva11019
- iOS GitLab版本管理需要忽略的文件
- 再议GCC编译时的静态库依赖次顺问题
- HelloJSP!——内置对象编程题
- ionic侧边栏字母导航
- hdu2191 悼念512汶川大地震遇难同胞——珍惜现在,感恩生活(多重背包)
- AC自动机通配符匹配
- js制作一个跳转提示页面
- 监控 snmpd服务
- 枚举
- Hibernate-Validation的使用
- 艾普视达的一个流程五篇跑下来有内存,一次一个block
- AC自动机总结
- inception安装步骤---自己整理的安装步骤
- Android 适用各种布局的loading加载框