对于字符串A,其中绝对不含有字符’.’和’’。再给定字符串B,其中可以含有’.’或’’,’’字符不能是B的首字符,并且任意两个’’字符不相邻。exp中的’.’代表任何一个字符,B中的’’表示’’的前一个字符可以有0个或者多个。请写一个函数,判断A是否能被B匹配。
#include <iostream> #include <algorithm> using namespace std; /* str:i exp:j bool f(i,j):str中i开头的字符串能否匹配exp中j开头的字符串 j+1位置上是否为* 1.j是最后一个字符 2.j+1有字符不是* i位置的字符必须与j位置的字符相匹配成功(j位置字符与i位置相等或j位置为'.'),配不上直接返回false,如果配上再看j+1和i+1 3.j+1位置有字符是* 1>j位置字符为普通字符,考虑j+2配i开头的整体 2>j位置与i位置字符匹配,考虑j+2位置与i开头以及以后相应的位置匹配(str的前缀不停变化) */ //暴力递归 bool match(const string &str,const string &exp,int i,int j) { if(j==exp.size()) return i==str.size(); //j位置有字符 if(j+1==exp.size()||exp.at(j+1)!='*') return i!=str.size()&&(str.at(i)==exp.at(j)||exp.at(j)=='.')&&match(str,exp,i+1,j+1); //j+1有字符且是'*' while(i!=str.size()&&(exp.at(j)==str.at(i)||exp.at(j)=='.')) { if(match(str,exp,i,j+2)) return true; ++i; } return match(str,exp,i,j+2); } //dp bool is_valid(const string &str,const string &exp) { if(find(str.begin(),str.end(),'.')!=str.end()||find(str.begin(),str.end(),'*')!=str.end()) return false; if(find(exp.begin(),exp.end(),'*')==exp.begin()||str.find("**")!=string::npos) return false; return true; } bool match1(const string& str, const string& exp) { if(str.empty()||exp.empty()) return false; if(!is_valid(str,exp)) return false; //填表 vector<vector<bool> > m(str.size()+1,vector<bool>(exp.size()+1)); m.at(m.size()-1).at(m.at(0).size()-1)=true; for(int j=m.at(0).size()-2;j>=0;j-=2) { if(exp.at(j)!='*'&&exp.at(j+1)=='*') m.at(str.size()).at(j)=true; else break; } if(str.size()>0&&exp.size()>0) if(exp.at(exp.size()-1)=='.'||str.at(str.size()-1)==exp.at(exp.size()-1)) m.at(str.size()-1).at(exp.size()-1)==true; for(int i=str.size()-1;i>=0;--i) { for(int j=exp.size()-2;j>=0;--j) { if(exp.at(j+1)!='*') m.at(i).at(j)=(str.at((i)==exp.at(j)||exp.at(j)=='.'))&&m.at(i+1).at(j+1); else { int si=i; while(si!=str.size()&&(str.at(si)==exp.at(j)||exp.at(j)=='.')) { if(m.at(si).at(j+2)) { m.at(i).at(j)=true; break; } ++si; } if(m.at(i).at(j)!=true) m.at(i).at(j)=m.at(si).at(j+2); } } } return m.at(0).at(0); } int main() { string str("abc"); string exp("a.c"); cout<<match(str,exp,0,0)<<endl; cout<<match1(str,exp)<<endl; return 0; }