59 lines
1.7 KiB
C#
59 lines
1.7 KiB
C#
public class Solution
|
|
{
|
|
public bool IsMatch(string s, string p) => IsMatch(null, s, p);
|
|
|
|
private bool IsMatch(char? prev, ReadOnlySpan<char> str, ReadOnlySpan<char> pattern)
|
|
{
|
|
if (pattern.Length == 0 && str.Length == 0)
|
|
return true;
|
|
if (str.Length == 0)
|
|
{
|
|
if (CanBeEmpty(pattern))
|
|
return true;
|
|
return false;
|
|
}
|
|
if (pattern.Length == 0)
|
|
return false;
|
|
var sym = str[0];
|
|
var p = pattern[0];
|
|
// раскрытая звёздочка
|
|
var pSymOrDot = p == '*' ? prev : p; // превращаем звёздочку в символ или точку
|
|
// ожидаемый текущий символ, конкретный
|
|
var pSym = pSymOrDot == '.' ? sym : pSymOrDot;
|
|
|
|
|
|
// следующий символ *
|
|
if (pattern.Length > 1 && pattern[1] == '*')
|
|
{
|
|
var match = false;
|
|
var i = 0;
|
|
do
|
|
{
|
|
match |= IsMatch(i > 0 ? p : prev, str[i..], pattern[2..]);
|
|
if (match || i == str.Length || str[i] != p && p != '.')
|
|
break;
|
|
i++;
|
|
}
|
|
while (i <= str.Length);
|
|
return match;
|
|
}
|
|
else if (sym != pSym)
|
|
{
|
|
return false;
|
|
}
|
|
else
|
|
{
|
|
return IsMatch(pSymOrDot, str[1..], pattern[1..]);
|
|
}
|
|
}
|
|
|
|
private bool CanBeEmpty(ReadOnlySpan<char> pattern)
|
|
{
|
|
if (pattern.Length % 2 == 1)
|
|
return false;
|
|
for (var i = 1; i < pattern.Length; i += 2)
|
|
if (pattern[i] != '*')
|
|
return false;
|
|
return true;
|
|
}
|
|
} |