我是靠谱客的博主 冷艳月亮,最近开发中收集的这篇文章主要介绍leetcode 面试题16.18.模式匹配:复现双百算法(分类别讨论),C++带详细注解,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

leetcode 面试题16.18.模式匹配:复现双百算法(分类别讨论),C++带详细注解


分成5类讨论,定义了两个辅助函数:

class Solution {
public:
bool kSegment(string value,int k)//判断value能否被分成k个一样的字串
{
    int len=value.size();//求value长度
    if(len%k!=0) return false;//长度不是k的整数倍,不能
    int m=len/k;//求k等分后每个字符串的长度
    for(int i=m;i<len;i+=m)//看k个字符串是否相等
    {
        if(value.substr(i,m)!=value.substr(0,m)) return false;//出现与第一个字串不等的情况,返回假
    }
    return true;//都等返回真
}

bool check(string pattern,string value,int len_a,int len_b)//pattern,value都不空,给定a,b模式的长度,判断能否匹配
{//pattern 中ab都有,且ab不为空串
    string str[2]={"",""};//存放a,b所代表的串
    for(int i=0,j=0;i<pattern.size();i++)//遍历pattern
    {
        if(pattern[i]=='a')//遇到a
        {
            if(str[0]=="") str[0]=value.substr(j,len_a);//第一次遇到就把此处往后len_a个字符赋给str[0]
            else//不是第一次遇到
            {
                if(value.substr(j,len_a)!=str[0]) return false;//检查此处往后len_a个元素是否和a相同,不同为假
            }
            j+=len_a;//value往后退len_a个元素
            
        }
        if(pattern[i]=='b')//遇到b
        {
            if(str[1]=="") str[1]=value.substr(j,len_b);//第一次遇到就把此处往后len_b个字符赋给str[1]
            else//不是第一次遇到
            {
                if(value.substr(j,len_b)!=str[1]) return false;//检查此处往后len_b个元素是否和b相同,不同为假
            }
            j+=len_b;//value往后退len_a个元素
            
        }
    }
    return str[0]!=str[1];//若a,b不同返回真,相同则不行
}
    int cnt[2]={0};//全局变量,存放pattern中a,b各出现的次数
    bool patternMatching(string pattern, string value) {//分情况讨论
        if(pattern.empty()) return value.empty();//1.pattern空,value空为真否则为假
        if(value.empty())//2.patt不空 2.1若value为空,看pattern是否只有一种字符组成,该字符代表空串
        {
            int len=pattern.size();//长度
            for(int i=1;i<len;i++)//遍历pattern
            {
                if(pattern[i]!=pattern[0]) return false;//不止一种字符组成
            }
            return true;//是只有一种字符
        }
        //2.2pattern value都不空
        for(auto str:pattern) cnt[str-'a']++;//巧妙利用ascII码统计
        //2.2.1判断pattern中是否只有一种字符
        if(cnt[0]==0) return kSegment(value, cnt[1]);//返回value能否被分成cnt[1]个一样的串
        if(cnt[1]==0) return kSegment(value, cnt[0]);//同样
        //2.2.2pattern中a,b都有,看能否把其中一个当作空串,
        if(kSegment(value, cnt[0])) return true;//把b当空串,且value能被分成a的个数个一样的串,则为真
        if(kSegment(value, cnt[1])) return true;//同样
        //2.2.3 pattern中a,b都有且都不为空,value也不空,此时需要讨论a,b代表串的长度
        int m=pattern.size(),n=value.size();//求长度
        for(int len_a=1;len_a*cnt[0]<=n-cnt[1];len_a++)//枚举a长度:最小为1,最大为n-cnt[1]
        {
            if((n-cnt[0]*len_a)%cnt[1]!=0) continue;//b字符串长度不为整数跳过
            int len_b=(n-cnt[0]*len_a)/cnt[1];//b串长度
            if(check(pattern,value,len_a,len_b)) return true;//找到一种符合条件的
        }
        return false;//没有符合条件的
    }
};

最后

以上就是冷艳月亮为你收集整理的leetcode 面试题16.18.模式匹配:复现双百算法(分类别讨论),C++带详细注解的全部内容,希望文章能够帮你解决leetcode 面试题16.18.模式匹配:复现双百算法(分类别讨论),C++带详细注解所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(39)

评论列表共有 0 条评论

立即
投稿
返回
顶部