原题
Given an input string (s) and a pattern §, implement regular expression matching with support for ‘.’ and ‘’.
‘.’ Matches any single character.
'’ Matches zero or more of the preceding element.
The matching should cover the entire input string (not partial).
Note:
s could be empty and contains only lowercase letters a-z.
p could be empty and contains only lowercase letters a-z, and characters like . or *.
即给定字符串s(全部小写), 一个正则表达式p(仅包含’.‘和’*'符号, 字母小写). 输出字符串是否完全匹配.
先写测试代码
import unittest
from main import Solution
class TestMain(unittest.TestCase):
def setUp(self):
self.solver = Solution()
self.cases = [
{
"feed": 'abcdefggghi',
"regexp": 'a..defg*hi',
"want": True
},
{
"feed": 'some text',
"regexp": '.*text',
"want": True
},
{
"feed": 'abcddddffg',
"regexp": 'n*ab.*g',
"want": True
},
{
"feed": 'abcddddffg',
"regexp": 'n.ab.*g',
"want": False
},
{
"feed": '',
"regexp": 'n.ab.*g',
"want": False
},
{
"feed": 'abcdef',
"regexp": 'abcdefgh',
"want": False
},
{
"feed": 'aab',
"regexp": 'c*a*b',
"want": True
},
]
def testCase(self):
for case in self.cases:
res = self.solver.isMatch(case["feed"], case["regexp"])
self.assertEqual(res, case["want"], "feed:{}, exp:{}".format(case["feed"], case["regexp"]))
if __name__ == '__main__':
suite = unittest.TestLoader().loadTestsFromTestCase(TestMain)
unittest.TextTestRunner(verbosity=2).run(suite)
解法
一般是采用动态规划法, 假设s长度为m, p长度为n, 设置一个dp[m+1][n+1]数组保存判断各种情况的结果。
- 如果 p[j] == ‘*’ 则 dp[i][j]为True的情况为:
- dp[i][j-1] == True; 如 s=‘abcd’, p=‘a.*cd’, i=1, j=2;
- dp[i-1][j] 且( s[i-1] == p[j-1] or p[j-1] ==’.’)
- 如果p[j] != ‘*’ 则dp[i][j]为True的情况为:
dp[i-1][j] and (s[i-1] == p[j] or p[j] == ‘.’)
实际时,将dp[0][0]表示为s=’’, p=’'的情况; 完整代码如下:
class Solution(object):
def isMatch(self, s, p):
m = len(s)
n = len(p)
dp = [[False] * (n+1) for _ in range(m+1)]
dp[0][0] = True
for i in range(0, m+1):
for j in range(1, n+1):
if p[j-1] == '*':
dp[i][j] = dp[i][j-2] or ( i>0 and (s[i-1] == p[j-2] or p[j-2] == '.') and dp[i-1][j])
else:
dp[i][j] = i>0 and dp[i-1][j-1] and (s[i-1] == p[j-1] or p[j-1] == '.')
return dp[m][n]
运行
> python3 test.py
testCase (__main__.TestMain) ... ok
----------------------------------------------------------------------
Ran 1 test in 0.001s
OK