I also liked the code but it does not pass some of my unit tests. So here is my improvement. Like Gurce said it might not be perfect but it is improved.
int is_match(const char* line, const char* pattern)
{
// returns 1 (true) if there is a match
// returns 0 if the pattern is not whitin the line
int wildcard = 0;
const char* last_pattern_start = 0;
const char* last_line_start = 0;
do
{
if (*pattern == *line)
{
if(wildcard == 1)
last_line_start = line + 1;
line++;
pattern++;
wildcard = 0;
}
else if (*pattern == '?')
{
if(*(line) == '\0') // the line is ended but char was expected
return 0;
if(wildcard == 1)
last_line_start = line + 1;
line++;
pattern++;
wildcard = 0;
}
else if (*pattern == '*')
{
if (*(pattern+1) == '\0')
{
return 1;
}
last_pattern_start = pattern;
//last_line_start = line + 1;
wildcard = 1;
pattern++;
}
else if (wildcard)
{
if (*line == *pattern)
{
wildcard = 0;
line++;
pattern++;
last_line_start = line + 1 ;
}
else
{
line++;
}
}
else
{
if ((*pattern) == '\0' && (*line) == '\0') // end of mask
return 1; // if the line also ends here then the pattern match
else
{
if (last_pattern_start != 0) // try to restart the mask on the rest
{
pattern = last_pattern_start;
line = last_line_start;
last_line_start = 0;
}
else
{
return 0;
}
}
}
} while (*line);
if (*pattern == '\0')
{
return 1;
}
else
{
return 0;
}
}
Here is the test cases it does however pass:
TEST_CASE("is_match") {
REQUIRE( is_match("abcdefg", "abcdefg") == 1);
REQUIRE( is_match("abcdefg", "aacdefg") == 0);
REQUIRE( is_match("abcdefg", "*cde*") == 1);
REQUIRE( is_match("abcdefg", "cde*") == 0);
REQUIRE( is_match("abcdefg", "*cde") == 0);
REQUIRE( is_match("abcdfcdefg", "**cde") == 0);
REQUIRE( is_match("abcdfcdefg", "**cde*") == 1);
REQUIRE( is_match("abcdexxxcdefg", "*cdef*cdef") == 0);
REQUIRE( is_match("abcxxdexxxcdefg", "*xxx*?g") == 1);
REQUIRE( is_match("abcdexxxcdefg", "*cdef*cdef*") == 0);
REQUIRE( is_match("abcdefg", "*cdf*cdef*") == 0);
REQUIRE( is_match("abcdefg", "*") == 1);
REQUIRE( is_match("", "*") == 1);
REQUIRE( is_match("d", "?") == 1);
CHECK ( is_match("ddd", "*?") == 1);
CHECK ( is_match("ddd", "?*") == 1);
CHECK ( is_match("ddd", "???") == 1);
CHECK ( is_match("ddd", "*?*") == 1);
CHECK ( is_match("", "?") == 0);
REQUIRE( is_match("abcdefg", "*?cde*") == 1);
REQUIRE( is_match("abcdefg", "??cde??") == 1);
REQUIRE( is_match("abcdefg", "??cde?") == 0);
REQUIRE( is_match("abcdefg", "ppppp") == 0);
REQUIRE( is_match("abcdefg", "??c??") == 0);
REQUIRE( is_match("abcdefxxxcdefg", "*cdef*cdef?") == 1);
REQUIRE( is_match("abcdefxxxcdefg", "*cdef*cdef*") == 1);
REQUIRE( is_match("abcdefxxxcdefg", "*cdef*cdef") == 0);
}
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4