Okay, this is more serious, 31 patterns are needed to exhaust your request. 0 internal '*': Step01: *ABCDE* 1 internal '*': Step02: *ABCD*E* Step03: *ABC*DE* Step04: *AB*CDE* Step05: *A*BCDE* 2 internal '*': Step06: *A*B*CDE* Step07: *A*BC*DE* Step08: *A*BCD*E* Step09: *AB*C*DE* Step10: *AB*CD*E* Step11: *ABC*D*E* 3 internal '*': Step12: *A*B*C*DE* Step13: *A*B*CD*E* Step14: *A*BC*D*E* Step15: *AB*C*D*E* Above 15 patterns are optional, they would yield hits with 'high' rank earlier than all the 31 ones below. Finding all substrings (without elision): Step01+15: *A*B*C*D*E* Finding all substrings (with elision): C(5,4) equals number of wildcard patterns, 5 choose 4 = 5!/(4!*(5-4)!) = 5*4*3*2*1/(4*3*2*1*1) = 5 Step02+15: *B*C*D*E* Step03+15: *A*C*D*E* Step04+15: *A*B*D*E* Step05+15: *A*B*C*E* Step06+15: *A*B*C*D* C(5,3) equals number of wildcard patterns, 5 choose 3 = 5!/(3!*(5-3)!) = 5*4*3*2*1/(3*2*1*2*1) = 10 Step07+15: *A*B*C* Step08+15: *A*B*D* Step09+15: *A*B*E* Step10+15: *A*C*D* Step11+15: *A*C*E* Step12+15: *A*D*E* Step13+15: *B*C*D* Step14+15: *B*C*E* Step15+15: *B*D*E* Step16+15: *C*D*E* C(5,2) equals number of wildcard patterns, 5 choose 2 = 5!/(2!*(5-2)!) = 5*4*3*2*1/(2*1*3*2*1) = 10 Step17+15: *A*B* Step18+15: *A*C* Step19+15: *A*D* Step20+15: *A*E* Step21+15: *B*C* Step22+15: *B*D* Step23+15: *B*E* Step24+15: *C*D* Step25+15: *C*E* Step26+15: *D*E* C(5,1) equals number of wildcard patterns, 5 choose 1 = 5!/(1!*(5-1)!) = 5*4*3*2*1/(1*4*3*2*1) = 5 Step27+15: *A* Step28+15: *B* Step29+15: *C* Step30+15: *D* Step31+15: *E* In essence the number e.g. C(5,4) equals all ways to order any four of five elements, which is 5!/(5-4)! divided by all ways to order any group of 4, which is 4!. Thus, the number of distinct ways to choose 4 out of 5 is 120 divided by 24. By chance I wrote the fastest wildcard search function (iterative) so these 31 patterns won't be much of a problem:
int WildcardMatch_Iterative_Kaze(const char* mask, const char* name) {
// Revision 1:
/*
const char* maskSTACK;
const char* nameSTACK;
int BacktrackFlag = 0;
Backtrack:
for (nameSTACK = name, maskSTACK = mask; *nameSTACK; ++nameSTACK, ++maskSTACK) {
if (*maskSTACK == '&') {
mask = maskSTACK+1;
if (!*mask) return 1;
name = nameSTACK;
BacktrackFlag = -1;
goto Backtrack;
}
//else if (*maskSTACK == '+') {
//} else {
else if (*maskSTACK != '+') {
//if (tolower(*nameSTACK) != tolower(*maskSTACK)) {