-----Edit by ZhuSenlin HDU
設計萬用字元匹配演算法,其中*號可以匹配任意多個字元,?號可以匹配任意一個字元。例如12345和12*、12*?以及12*4?等都匹配。
函數原型為:bool match(const char* str, const char* strpattern);
分析:利用動態規劃來解決。
此題類似與LCS問題。假設字串A[i]代表前i+1個子字串,B[j]代表前j+1個子字串,那麼A[i]與B[j]是否匹配可以由A[i-1],B[j-1];A[[i-1],B[j];以及A[i]B[j-1]結合當前A[i]與B[j]的字元來確定。
A[i]與B[j]匹配等價於
1、A[i-1]與B[j-1]匹配並且(A[i]==B[j]|| A[i]==* || (A[i]==’?’ && B[j] != ‘\0’))
2、A[i-1]與B[j]匹配並且(A[i]==’*’)
3、A[i]與B[j-1]匹配並且(A[i]==’*’|| (A[i-1]==’*’ && (A[i] == B[j] || (A[i]==’?’ && B[j] != ‘\0’))))
之間任何一個成立
代碼如下:
bool match_string(const char* str, const char* strpattern){int nStr = strlen(str);int nPatt = strlen(strpattern);int** pTable = new int* [nStr+1];for(int k = 0; k <= nStr; k++) {pTable[k] = new int [nPatt+1];memset(pTable[k],0,(nPatt+1)*sizeof(int));}pTable[0][0]=1;for(int i=1; i <= nStr; i++){for(int j=1;j <= nPatt; j++){if(pTable[i-1][j-1] == 1 && (strpattern[j-1] == str[i-1]|| (strpattern[j-1] == '?' && str[i-1] != '\0')|| strpattern[j-1] == '*')){pTable[i][j] = 1;}else if(pTable[i][j-1] == 1 && ((strpattern[j-1] == '*') || (j > 1 && strpattern[j-2] == '*'&&((strpattern[j-1] == '?' && str[i-1] != '\0')||strpattern[j-1] == str[i-1])))) {pTable[i][j] = 1;}else if (pTable[i-1][j] == 1 && strpattern[j-1] == '*') {pTable[i][j] = 1;}}}bool ret = (pTable[nStr][nPatt] == 1 ? true : false);for(int k = 0; k <= nStr; k++)delete [] pTable[k];delete pTable;return ret;}
測試代碼如下:
int main(int argc, char** argv){if(match_string(argv[1],argv[2])){cout << argv[1] << " and " << argv[2] << " matched!" << endl;}elsecout << argv[1] << " and " << argv[2] << " are not matched!" << endl;return 0;}