该程序只满足匹配第一个相同的字符串,对于出现第二个相同字符的字符串无法解决。
#include <iostream> #include <string> #include <algorithm> using namespace std; int IsMatch(string rule,string sub) { int k=0; int c=0; while(k<rule.length()&&c<sub.length()) { if(rule[k]=='?') { ++k; ++c; continue; } if(rule[k]=='*') { while(rule[k+1]!=sub[c]) { if(sub[c]=='#') return 0; ++c; } ++k; } if(rule[k]!=sub[c]) return 0; ++k; ++c; } if(rule[--k]==sub[--c]) return 1; else return 0; } string ToLower(string ss) { string::iterator itr; for(itr=ss.begin();itr!=ss.end();itr++) { *itr=tolower(*itr); } return ss; } int main() { string rule,sub; cin>>rule>>sub; rule=ToLower(rule); sub=ToLower(sub); rule.append("#"); sub.append("#"); if(IsMatch(rule,sub)) cout<<"true"<<endl; else cout<<"false"<<endl; }
在网上搜了下,这段代码是可行的,贴出来进行比较,这段代码是寻找与模式匹配字符串一致的起始位位置,类似于搜索:
http://m.blog.csdn.net/blog/kangroger_11109/22610391
#include<iostream> using namespace std; int find(char *substr,int start1,char *str,int start2) { int length1=strlen(substr);//子串长度 int length2=strlen(str);//母串长度 int result=-1;//最终要返回的结果 int current; for(int i=start2;i<=length2;i++)//start2为母串搜索的其实位置 { if(i==length2+1)//搜索失败 return -1; result=i; current=i; for(int k=start1;k<=length1;k++)//start1为子串搜索的其实位置 { if(k==length1-1) return result; if(substr[k]==str[current]||substr[k]=='?') { current++; } else if(substr[k]=='*')//遇到*通配符,代表任何一个或者多个或者0个字符 { if(-1==find(substr,k+1,str,current)) return -1; else return result; } else break; } } } int main() { char *substr=(char*)malloc(21*sizeof(char)); char *str=(char*)malloc(21*sizeof(char)); cin>>substr; cin>>str; cout<<find(substr,0,str,0); return 0; }
(1)我一开始的思路并未使用到递归的思想,而且一找到与第一个与模式字符*后第一个字母匹配的字符后,就不考虑后面还有匹配的情况,导致如果第二个字母不匹配,就直接返回不匹配。在我设计的算法当中,无法规避这个情况。下一段代码在一个for循环当中,把匹配字符的所有字符都遍历一遍。内层for是匹配当前模式字符串,当有匹配字符时,即进入 。一旦某次匹配不成功,即跳出内层for循环。继续外层for循环,重新开始寻找下一个匹配的地方。
(2)应该以匹配字符为主循环,我的却是以模式字符串为主循环。
结合以上思路,还需要改进,才能运用到当前华为的oj中。
打算在我写好的程序上进行修改,简单来说,就是在发现"*"字符串后,加一个for,把后面的都轮一遍,(递归),如果for循环一轮后,没有找到,返回false。
#include <iostream> #include <string> #include <algorithm> using namespace std; int IsMatch(string rule,string sub) { int k=0; int c=0; while(k<rule.length()&&c<sub.length()) { //改进部分 if(rule[k]=='#'||sub[c]=='#') { if(rule[k]=='#'&& sub[c]=='#') return 1; else return 0; } //改进部分^ if(rule[k]=='?') { ++k; ++c; continue; } if(rule[k]=='*') { //改进部分 for(int n=c;n<sub.length();n++) { if(IsMatch(rule.substr(k+1),sub.substr(n))) return 1; } return 0; //改进部分^ } if(rule[k]!=sub[c]) return 0; ++k; ++c; } } string ToLower(string ss) { string::iterator itr; for(itr=ss.begin();itr!=ss.end();itr++) { *itr=tolower(*itr); } return ss; } int main() { string rule,sub; cin>>rule>>sub; rule=ToLower(rule); sub=ToLower(sub); rule.append("#"); sub.append("#"); if(IsMatch(rule,sub)) cout<<"true"<<endl; else cout<<"false"<<endl; }