zoukankan      html  css  js  c++  java
  • 第19题:正则表达式匹配

    题目描述

    请实现一个函数用来匹配包括'.'和'*'的正则表达式。模式中的字符'.'表示任意一个字符,而'*'表示它前面的字符可以出现任意次(包含0次)。 在本题中,匹配是指字符串的所有字符匹配整个模式。例如,字符串"aaa"与模式"a.a"和"ab*ac*a"匹配,但是与"aa.a"和"ab*a"均不匹配

    考点:

    正则表达式

    递归

    字符串

    思路:

    bool match(char* str,char* pattern):

    1.str||pattern为nullptr,返回false;

    2.进入matchCore函数

    bool matchCore(char* str,char* pattern):

    1.都是结束符,返回true;

    2.模式为结束符,字符串不是,返回false;

    3. 如果*(pattern + 1) == '*'时,有两种情况:

    3.1   如果 *str 和 *前面的字符 *pattern相匹配,  有三种匹配方式:

    3.1.1  直接无视*,即 *前面的字符 重复0次,str,pattern+2,直接进入下一机制

    3.1.2  *前面的字符 重复1次,str+1,pattern+2 ,进入下一机制

    3.1.3  *前面的字符 重复(1+n)次,str+1,pattern,留在这个机制

    3.2 否则,str第一个字符 *str 和 *前面的字符 *pattern 不匹配,

    直接无视*,重复零次,str ,pattern+2,直接进入下一机制

    4.检查两个字符是否匹配:

    4.1 如果*pattern == '.' && *str != '', 匹配  。

    4.2 或者,如果*str == *pattern,匹配。

     当模式和字符串的字符相匹配的时候,就匹配后面的字符。str+1,pattern+1 

    第一遍

    bool matchCore(const char* str, const char* pattern);
    
    bool match(const char* str, const char* pattern)
    {
        //1.如果模式或者字符串其中有nullptr,返回假
        if(str == nullptr || pattern == nullptr)
            return false;
        //2.开始递归匹配
        return matchCore(str, pattern);
    }
    
    bool matchCore(const char* str, const char* pattern)
    {
    	//1.递归结束条件:模式和字符串都匹配到了结束,返回真
    	if (*str == ''&&*pattern == '')
    		return true;
    	//2.递归结束条件:如果模式先结束,字符串还没结束,返回假
    	if (*str != ''&&*pattern == '')
    		return false;
    
    	//3.先判断pattern 的下一个字符是否为 *, 如果是,则2种情况,4种匹配方法
    	if (*(pattern + 1) == '*')
    	{
    		//3.1 情况一:当*str与*pattern 匹配 时,有3种匹配方法
    		if (*str == *pattern || *pattern == '.'&&*str != '')
    			//3.1.1 无视 * ,*重复0次,进入下一机制 
    			return matchCore(str, pattern + 2) ||
    			//3.1.2 *重复1次,进入下一机制 
    			matchCore(str + 1, pattern + 2) ||
    			//3.1.3 *重复多次,留在这一机制 
    			matchCore(str + 1, pattern);
    		//3.2 情况二:当*str与*pattern 不匹配 时,无视 * ,*重复0次,进入下一机制 
    		else
    			return matchCore(str, pattern + 2);
    
    	}
    
    	//4. 直接匹配,如果两个相等,就匹配下一个
    	if (*str == *pattern || *pattern == '.'&&*str != '')
    		return matchCore(str+1,pattern+1);
    
    	//5. 如果两个字符不匹配,就返回假
    	return false;
    }

     第二遍

     注意——>>  

    1. if(*str==*pattern||(*str!=''&&*pattern=='.'))//后面的要加括号

    2. 

    //2.递归结束条件 失败:pattern先结束,字符串还没结束,返回假
            if(*str!=''&&*pattern=='')
                return false;

    匹配是指 字符串的所有字符匹配整个模式。只存在模式比字符串长的情况,因为模式中有*可以无视。

    所以不能写 

     if(*str==''&&*pattern!='')
                return false;
    class Solution {
    public:
        bool matchCore(char* str,char* pattern)
        {
            //1.递归结束条件 成功:str和pattern都匹配到结束符,返回真
            if(*str==''&&*pattern=='')
                return true;
            //2.递归结束条件 失败:pattern先结束,字符串还没结束,返回假
            if(*str!=''&&*pattern=='')
                return false;
            
            //3.判断模式下一个字符 是*
            if(*(pattern+1)=='*')
            {
                //3.1 情况一:如果模式和字符串的字符匹配
                if(*str==*pattern||(*str!=''&&*pattern=='.'))//后面的要加括号
                    //3.1.1 无视*,直接进入下一机制
                    return matchCore(str,pattern+2)
                    //3.1.2 *重复一次,进入下一机制
                    ||matchCore(str+1,pattern+2)
                    //3.1.3 *重复多次,留在这个机制
                    ||matchCore(str+1,pattern);
                //3.2 情况二:模式和字符串不匹配,无视*,进入下一个机制
                return matchCore(str,pattern+2);
            }        
            //4.否则,如果当前字符串和模式匹配,就匹配下一个字符
            else if(*str==*pattern||(*str!=''&&*pattern=='.'))
                return matchCore(str+1,pattern+1);
            
            //5.如果都不匹配,返回空
            return false;     
                
        }
        
        
        bool match(char* str, char* pattern)
        {
            //1.如果str或者pattern有空指针,返回假
            if(str==nullptr||pattern==nullptr)
                return false;
            
            //2.递归匹配
            return matchCore(str,pattern);
        
        }
        
        
    };

    网友的

    链接:https://www.nowcoder.com/questionTerminal/45327ae22b7b413ea21df13ee7d6429c
    来源:牛客网
    
    /*
        解这题需要把题意仔细研究清楚,反正我试了好多次才明白的。
        首先,考虑特殊情况:
             1>两个字符串都为空,返回true
             2>当第一个字符串不空,而第二个字符串空了,返回false(因为这样,就无法
                匹配成功了,而如果第一个字符串空了,第二个字符串非空,还是可能匹配成
                功的,比如第二个字符串是“a*a*a*a*”,由于‘*’之前的元素可以出现0次,
                所以有可能匹配成功)
        之后就开始匹配第一个字符,这里有两种可能:匹配成功或匹配失败。但考虑到pattern
        下一个字符可能是‘*’, 这里我们分两种情况讨论:pattern下一个字符为‘*’或
        不为‘*’:
              1>pattern下一个字符不为‘*’:这种情况比较简单,直接匹配当前字符。如果
                匹配成功,继续匹配下一个;如果匹配失败,直接返回false。注意这里的
                “匹配成功”,除了两个字符相同的情况外,还有一种情况,就是pattern的
                当前字符为‘.’,同时str的当前字符不为‘’。
              2>pattern下一个字符为‘*’时,稍微复杂一些,因为‘*’可以代表0个或多个。
                这里把这些情况都考虑到:
                   a>当‘*’匹配0个字符时,str当前字符不变,pattern当前字符后移两位,
                    跳过这个‘*’符号;
                   b>当‘*’匹配1个或多个时,str当前字符移向下一个,pattern当前字符
                    不变。(这里匹配1个或多个可以看成一种情况,因为:当匹配一个时,
                    由于str移到了下一个字符,而pattern字符不变,就回到了上边的情况a;
                    当匹配多于一个字符时,相当于从str的下一个字符继续开始匹配)
        之后再写代码就很简单了。
    */
    class Solution {
    public:
        bool match(char* str, char* pattern)
        {
            if (*str == '' && *pattern == '')
                return true;
            if (*str != '' && *pattern == '')
                return false;
            //if the next character in pattern is not '*'
            if (*(pattern+1) != '*')
            {
                if (*str == *pattern || (*str != '' && *pattern == '.'))
                    return match(str+1, pattern+1);
                else
                    return false;
            }
            //if the next character is '*'
            else
            {
                if (*str == *pattern || (*str != '' && *pattern == '.'))
                    return match(str, pattern+2) || match(str+1, pattern);
                else
                    return match(str, pattern+2);
            }
        }
    };
  • 相关阅读:
    ThinkPHP5 API 文档
    【转】移动web页面使用字体的思考
    【原】移动web页面兼容处理的思考
    20140829分享正则大纲
    javascript reverse string
    备忘“与”、“非”、“或”、“异或” 运算
    关于 Apple Metal API 的一些想法
    transform:rotate在手机上显示有锯齿的解决方案
    JS正则表达式验证数字(很全)
    去掉 wap (android/ios)网页等点击后的阴影
  • 原文地址:https://www.cnblogs.com/lightmare/p/10398762.html
Copyright © 2011-2022 走看看