模式匹配 A

题目

你有两个字符串,即pattern和value。 pattern字符串由字母"a"和"b"组成,用于描述字符串中的模式。例如,字符串"catcatgocatgo"匹配模式"aabab"(其中"cat"是"a",“go"是"b”),该字符串也匹配像"a"、"ab"和"b"这样的模式。但需注意"a"和"b"不能同时表示相同的字符串。编写一个方法判断value字符串是否匹配pattern字符串。

解题思路

简单的思路:设 l v l_v lv为value的长度, l a l_a la为a对应模式的长度, l b l_b lb为b对应模式的长度, c o u n t a count_a counta为a对应模式的个数, c o u n t b count_b countb为b对应模式的个数。则有:
c o u n t a × l a + c o u n t b × l b = l v count_a \times l_a +count_b \times l_b = l_v counta×la+countb×lb=lv
则在已知 c o u n t a count_a counta时,以 l a l_a la l b l_b lb为未知量得到二元一次方程,并且 l a ∈ [ 0 , l v c o u n t a + 1 ) l_a\in [0,\frac{l_v}{count_a}+1) la[0,countalv+1)
l a l_a la处于这个区间以保证 l b l_b lb大于等于0。接下来遍历 l a l_a la,得到分割后的子串是否满足要求。

0.统计a,b个数

统计pattern中a,b的个数

count_a = sum(1 for item in pattern if item == "a")
count_b = len(pattern)-count_a
1.特判
  1. 若a的个数小于b的个数,调换a、b以保证a最少出现1次,继而枚举a
if count_a < count_b:
    count_a, count_b = count_b, count_a
    pattern = "".join("a" if item == "b" else "b" for item in pattern)
  1. 若value为空,则要求pattern 中要么为空,要么只有a,等价于b的个数为0
if not value: return count_b == 0
  1. 若pattern为空而value不为空,则无法匹配。
if not pattern and value: return False
2.对于pattern和value都不为空时,两重遍历
for len_a in range(len(value)//count_a + 1):#遍历a的可能长度
    leftForb = len(value) - count_a * len_a#可能的b的总长度
    #看当前的分法是否满足要求(len(b)为大于等于0的整数)
    if (count_b == 0 and leftForb == 0) or (count_b != 0 and leftForb % count_b == 0):
        len_b = 0 if count_b == 0 else leftForb // count_b
        idx, Judge = 0, True
        value_a, value_b = None, None
        for ch in pattern:#对于确定a,b长度进行遍历模式
            if ch == "a":#对模式a的判断
                subChr = value[idx:idx+len_a]
                if not value_a:
                    value_a = subChr
                elif value_a != subChr:
                    Judge = False
                    break
                idx += len_a
            else:#对模式b的判断
                subChr = value[idx:idx+len_b]
                if not value_b:
                    value_b = subChr
                elif value_b != subChr:
                    Judge = False
                    break
                idx += len_b
        if Judge and value_a != value_b:#找到满足的value_a,value_b且两者不相等,返回T
            return True

代码

class Solution:
    def patternMatching(self, pattern: str, value: str) -> bool:
        #统计a、b的个数
        count_a = sum(1 for item in pattern if item == "a")
        count_b = len(pattern)-count_a
        #若a的个数小于b的个数,调换a、b以保证a最少出现1次,继而枚举a
        if count_a < count_b:
            count_a, count_b = count_b, count_a
            pattern = "".join("a" if item == "b" else "b" for item in pattern)
        #若value为空,则要求pattern 中要么为空,要么只有a,等价于b的个数为0
        if not value: return count_b == 0
        #若pattern为空而value不为空,则无法匹配
        if not pattern and value: return False
        #对于pattern和value都不为空时,遍历
        for len_a in range(len(value)//count_a + 1):
            leftForb = len(value) - count_a * len_a#可能的b的总长度
            #看当前的分法是否满足要求(len(b)为大于等于0的整数)
            if (count_b == 0 and leftForb == 0) or (count_b != 0 and leftForb % count_b == 0):
                len_b = 0 if count_b == 0 else leftForb // count_b
                idx, Judge = 0, True
                value_a, value_b = None, None
                for ch in pattern:
                    if ch == "a":#对模式a的判断
                        subChr = value[idx:idx+len_a]
                        if not value_a:
                            value_a = subChr
                        elif value_a != subChr:
                            Judge = False
                            break
                        idx += len_a
                    else:#对模式b的判断
                        subChr = value[idx:idx+len_b]
                        if not value_b:
                            value_b = subChr
                        elif value_b != subChr:
                            Judge = False
                            break
                        idx += len_b
                if Judge and value_a != value_b:#找到满足的value_a,value_b且两者不相等,返回T
                    return True
        return False#遍历完都没找到,返回F                 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值