C++ 带有通配符*与?的字符串匹配
题目:两个字符串,一个是普通字符串,另一个含有*和?通配符,*代表零个到多个任意字符,?代表一个任意字符,通配符可能多次出现。写一个算法,比较两个字符串是否相等。
发现许多公司笔试面试都有这道题目,于是自己搜了一下,从redis源码util.c源文件中可以找到这么一个函数,实际上glib中也有类似的实现
int stringmatch(const char *pattern, const char *string, int nocase) {
return stringmatchlen(pattern,strlen(pattern),string,strlen(string),nocase)
}
stringmatch可以满足上述题目的要求
#include <iostream> #include <string.h> using namespace std; int stringmatchlen(const char *pattern, int patternLen, const char *string, int stringLen, int nocase) { while(patternLen) { switch(pattern[0]) { case '*': while (pattern[1] == '*') { pattern++; patternLen--; } if (patternLen == 1) return 1; /** match */ while(stringLen) { if (stringmatchlen(pattern+1, patternLen-1, string, stringLen, nocase)) return 1; /** match */ string++; stringLen--; } return 0; /** no match */ break; case '?': if (stringLen == 0) return 0; /** no match */ string++; stringLen--; break; case '[': { int inot, match; pattern++; patternLen--; inot = pattern[0] == '^'; if (inot) { pattern++; patternLen--; } match = 0; while(1) { if (pattern[0] == '\\') { pattern++; patternLen--; if (pattern[0] == string[0]) match = 1; } else if (pattern[0] == ']') { break; } else if (patternLen == 0) { pattern--; patternLen++; break; } else if (pattern[1] == '-' && patternLen >= 3) { int start = pattern[0]; int end = pattern[2]; int c = string[0]; if (start > end) { int t = start; start = end; end = t; } if (nocase) { start = tolower(start); end = tolower(end); c = tolower(c); } pattern += 2; patternLen -= 2; if (c >= start && c <= end) match = 1; } else { if (!nocase) { if (pattern[0] == string[0]) match = 1; } else { if (tolower((int)pattern[0]) == tolower((int)string[0])) match = 1; } } pattern++; patternLen--; } if (inot) match = !match; if (!match) return 0; /** no match */ string++; stringLen--; break; } case '\\': if (patternLen >= 2) { pattern++; patternLen--; } /** fall through */ default: if (!nocase) { if (pattern[0] != string[0]) return 0; /** no match */ } else { if (tolower((int)pattern[0]) != tolower((int)string[0])) return 0; /** no match */ } string++; stringLen--; break; } pattern++; patternLen--; if (stringLen == 0) { while(*pattern == '*') { pattern++; patternLen--; } break; } } if (patternLen == 0 && stringLen == 0) return 1; return 0; } int stringmatch(const char *pattern, const char *string, int nocase) { return stringmatchlen(pattern,strlen(pattern),string,strlen(string),nocase); } int main(int argc, const char *argv[]) { char s1[100],s2[100]; while ( cin>>s1>>s2) { if(stringmatch(s1,s2,true){ std::cout << "yes" << std::endl; }else{ std::cout << "no" << std::endl; } } return 0; }
测试截图