OK! aa a not matched
OK! aa aa matched
OK! aaa aa not matched
OK! aa a* matched
OK! aa a** matched
OK! aab a**b matched
OK! aabb a**b matched
OK! ab ?* matched
OK! aab c*a*b not matched
OK! abcdefdefg abc*def not matched
OK! abefcdgiescdfimde ab*cd?i*de matched
写到这里,发现不是这种办法不好,没代码没有好好组织,而逻辑状态会随着代码的增加而变得混乱起
来。鉴于上面代码的逻辑,还可以构造出另几组测试数据来验证代码的错漏:
assert(solve, "abecdgiscdfidecde", "ab*cd?i*de", true);
assert(solve, "abcdgisdecdfideide","ab*cd?i*de", true);
以上这条测试前面的代码也是不能通过的,因为代码中对于 * 幻数的匹配是从短到长的尝试,而对于后
面的 * 幻数却没有这样做,所以产生逻辑错误,这里称之为幻数陷阱。现在倒是想重写代码,其实真的
应该好好想想如何组织代码逻辑,下面开始重构代码,只是部分逻辑功能:
bool isMatch(string s, string p) {
int m[512], k = 0, is = 0, ip = 0, ls = s.length(), lp = p.length();
unsigned short max_loop = -1, max_m = sizeof(m)/sizeof(int);
while(max_loop--){
if( ip<lp && ( p[ip]=='?' || is<ls && s[is]==p[ip] ) ){
ip++;
is++;
}else if( ip<lp && p[ip] == '*' ){
if( k>= max_m ) cout << "max_m " << __FILE__ << __LINE__ << endl;
m[k++] = is;
ip ++;
}else if( is==ls && ip==lp ){
return true;
}else return false;
}
if(!max_loop) cout << "max_loop " << __FILE__ << __LINE__ << endl;
}
尽管只是部分功能的实现,但测试效果来看,是有作用的,虽然从通过次数来讲还不乐观,但从代码的
结构上来看已经简洁了一个层次,这是最好的消息: