题解 | #字符串通配符 leetcode10动态规划 #
字符串通配符
https://www.nowcoder.com/practice/43072d50a6eb44d2a6c816a283b02036
''' 整体思路和leetcode 10. 一样, 唯一要小心的是 *号虽然不能匹配非数字和字母之外的字符, 但是可以通过0次匹配来兼容包含这种一场字符, 比如例子: reg = 't?t*1*.*' tgt = 'txt12.xls' ''' reg = input().strip().lower() tgt = input().lower() reg_len = len(reg) tgt_len = len(tgt) dot = '?' star = '*' dp_arr = [ [False] * (reg_len+1) for i in range(tgt_len + 1)] dp_arr[0][0] = True def can_match(a): a_lower = a.lower() return (a_lower>='a' and a_lower<='z') or (a_lower >='0' and a_lower <='9') def is_matcher(a): a_lower = a.lower() return a_lower == dot or a_lower == star for i in range(1, reg_len+1): if reg[i-1] in [dot, star]: dp_arr[0][i] = dp_arr[0][i-1] for i in range(0, tgt_len): idx = i+1 for j in range(0, reg_len): jdx = j+1 # 正则串目前位置是普通字符,直接普通匹配 if not is_matcher(reg[j]): if reg[j] == tgt[i]: dp_arr[idx][jdx] = dp_arr[idx-1][jdx-1] # 正则串目前是通配符,开始细分条件判断 else: #关键点! 即便当前的目标串字符是异常字符,但是-> # *号通配符可以通过0次匹配来兼容,不能跳过 if not can_match(tgt[i]): if reg[j] != star: continue #核心dp转移公式,详细参考leetcode No.10 if reg[j] == star: dp_arr[idx][jdx] = dp_arr[idx-1][jdx] or dp_arr[idx][jdx-1] else: dp_arr[idx][jdx] = dp_arr[idx-1][jdx-1] if dp_arr[tgt_len][reg_len]: print('true') else: print('false')