Die volle Leistungsfähigkeit regulärer Ausdrücke und endlicher Zustandsautomaten ist zur Lösung dieses Problems nicht erforderlich. Als Alternative gibt es eine relativ einfache Lösung durch dynamische Programmierung.
Match(i, j) sei 1, wenn es möglich ist, die Teilzeichenkette String [i..n-1] mit dem Teil-Muster Muster [j, m - 1], wobei n und m die Längen der String y Muster beziehungsweise. Andernfalls sei match(i, j) gleich 0.
Die Basisfälle sind:
-
match(n, m) = 1, können Sie eine leere Zeichenkette mit einem leeren Muster vergleichen;
-
match(i, m) = 0, kann man eine nicht leere Zeichenfolge nicht mit einem leeren Muster vergleichen;
Der Übergang ist in drei Fälle unterteilt, je nachdem, ob das aktuelle Teilmuster mit einem Zeichen, gefolgt von einem '*', oder einem Zeichen, gefolgt von einem '?', oder einfach mit einem Zeichen ohne nachfolgendes Sonderzeichen beginnt.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int is_match(char* pattern, char* string)
{
int n = strlen(string);
int m = strlen(pattern);
int i, j;
int **match;
match = (int **) malloc((n + 1) * sizeof(int *));
for(i = 0; i <= n; i++) {
match[i] = (int *) malloc((m + 1) * sizeof(int));
}
for(i = n; i >= 0; i--) {
for(j = m; j >= 0; j--) {
if(i == n && j == m) {
match[i][j] = 1;
}
else if(i < n && j == m) {
match[i][j] = 0;
}
else {
match[i][j] = 0;
if(pattern[j + 1] == '*') {
if(match[i][j + 2]) match[i][j] = 1;
if(i < n && pattern[j] == string[i] && match[i + 1][j]) match[i][j] = 1;
}
else if(pattern[j + 1] == '?') {
if(match[i][j + 2]) match[i][j] = 1;
if(i < n && pattern[j] == string[i] && match[i + 1][j + 2]) match[i][j] = 1;
}
else if(i < n && pattern[j] == string[i] && match[i + 1][j + 1]) {
match[i][j] = 1;
}
}
}
}
int result = match[0][0];
for(i = 0; i <= n; i++) {
free(match[i]);
}
free(match);
return result;
}
int main(void)
{
printf("is_match(dummy, dummy) = %d\n", is_match("dummy","dummy"));
printf("is_match(dumm?y, dummy) = %d\n", is_match("dumm?y","dummy"));
printf("is_match(dum?y, dummy) = %d\n", is_match("dum?y","dummy"));
printf("is_match(dum*y, dummy) = %d\n", is_match("dum*y","dummy"));
system("pause");
return 0;
}
Die Zeitkomplexität dieses Ansatzes ist O(n * m). Die Speicherkomplexität ist ebenfalls O(n * m), kann aber mit einer einfachen Änderung auf O(m) reduziert werden.