通配符匹配问题

问题:

给定一个字符串 (s) 和一个字符模式 (p) ,实现一个支持 '?' 和 '*' 的通配符匹配。

  '?' 可以匹配任何单个字符。

  '*' 可以匹配任意字符串(包括空字符串)。

  两个字符串完全匹配才算匹配成功。

说明:

  s 可能为空,且只包含从 a-z 的小写字母。

  p 可能为空,且只包含从 a-z 的小写字母,以及字符 ? 和 *

示例:

 

  输入:

 

  s = "acdcb"

 

  p = "a*c?b"

 

  输出: false

 

思路:

 

假设我们用两个指针分别指向s和p字符串中要匹配的位置,首先分析下通配符匹配过程中会有哪些情况是成功:

 

  1. s的字符和p的字符相等

  2. p中的字符是?,这时无论s的字符是什么都可以匹配一个

  3. p中遇到了一个*,这时无论s的字符是什么都没关系

  4. 之前的都不符合,但是p在之前的位置有一个*,我们可以从上一个*后面开始匹配

  5. s已经匹配完,但是p后面还有很多连续的`*

  6. 这里1和2的情况比较好处理,关键在于如何处理3和4的情况。当我们遇到一个*时,因为之后可能要退回至该位置重新匹配,我们要将它的下标记录下来,比如idxstar。但是,当我们连续遇到两次4的情况,如何保证我还是能继续匹配s,而不是每次都退回idxstar+1导致循环呢?所以我们还要记录一个idxmatch,用来记录用上一个*连续匹配到的s中的下标。最后,对于情况5,我们用一个循环跳过末尾的*跳过就行了。

 

代码:

 

package leetcode;


import java.util.Scanner;

public class Main {
    
    public static void main(String []args) {
        Scanner scanner =new Scanner(System.in);
        String s=null;
        String p=null;
        s=scanner.nextLine();
        p=scanner.nextLine();
        System.out.println(isMatch(s,p));
        
    }
    
    public static boolean isMatch(String s,String p) {
        int idp=0;
        int ids=0;
        int idxstar=-1;
        int idxmatch=0;
        
        
        while(ids<s.length()) {
            if(idp<p.length()&&(s.charAt(ids)==p.charAt(idp)||p.charAt(idp)=='?')){
                ids++;
                idp++;
            }else if(idp<p.length()&&p.charAt(idp)=='*') {
                idxstar=idp;
                idp++;
                idxmatch=ids;
            }else if(idxstar!=-1) {
                idp=idxstar+1;
                
                idxmatch++;
                ids=idxmatch;
                        
            }else {
                return false;
            }
        }
        while(idp<p.length()&&p.charAt(idp)=='*') {
            idp++;
        }
        
        return idp==p.length();
    }

}

 

 

 

 

 



posted @ 2018-08-21 15:33  orieam  阅读(549)  评论(0)    收藏  举报