Regular Expression Matching2015年6月24日

题目:

Implement regular expression matching with support for '.' and '*'.

'.' Matches any single character.
'*' Matches zero or more of the preceding element.

The matching should cover the entire input string (not partial).

The function prototype should be:
bool isMatch(const char *s, const char *p)

Some examples:
isMatch("aa","a") → false
isMatch("aa","aa") → true
isMatch("aaa","aa") → false
isMatch("aa", "a*") → true
isMatch("aa", ".*") → true
isMatch("ab", ".*") → true
isMatch("aab", "c*a*b") → true

思路:看大神的总结说是递归   反正鄙人完全没思路

解法1:

445 / 445 test cases passed.
Status: Accepted
Runtime: 624 ms
Submitted: 0 minutes ago

 

    public boolean isMatch(String s, String p) {
        if (p.contains(".") || p.contains("*")) {
            if (p.length() == 1 || p.charAt(1) != '*')
                return comp(s, p, s.length(), 0) && isMatch(s.substring(1), p.substring(1));
            for (int i = 0; i == 0 || comp(s, p, s.length(), i - 1); i++) {
                if (isMatch(s.substring(i), p.substring(2)))
                    return true;
            }
        }
        return s.equals(p);
    }

    private boolean comp(String s, String p, int sLen, int i) {
        return sLen > i && (p.charAt(0) == s.charAt(i) || p.charAt(0) == '.');
    }

解法2:

 

445 / 445 test cases passed.
Status: Accepted
Runtime: 612 ms
Submitted: 0 minutes ago

 

public class Solution {
    public boolean isMatch(String s, String p) {
        if (p.isEmpty()) {
            return s.isEmpty();
        }
    
        if (p.length() == 1 || p.charAt(1) != '*') {
            if (s.isEmpty() || (p.charAt(0) != '.' && p.charAt(0) != s.charAt(0))) {
                return false;
            } else {
                return isMatch(s.substring(1), p.substring(1));
            }
        }
    
        //P.length() >=2
        while (!s.isEmpty() && (s.charAt(0) == p.charAt(0) || p.charAt(0) == '.')) {  
            if (isMatch(s, p.substring(2))) { 
                return true;                     
            }                                    
            s = s.substring(1);
        }
    
        return isMatch(s, p.substring(2));
    }
}

解法3:有穷状态自动机

regular expression is the expression of regregular language, and regregular language can be expressed by a DFA.

I notice that nothing about DFA is talked about in the discuss,so I think I should post my codes to raise this topic.

During building the DFA, there's a small trick to make the code clean. 

enter image description here

 

445 / 445 test cases passed.
Status: Accepted
Runtime: 560 ms
Submitted: 0 minutes ago

 

public class Solution {
    String input;
    public boolean isMatch(String s, String p) {
        input=s;

        //----------building DFA------------
        Node start=new Node();
        Node pre=start;

        int i=0;
        while(i<p.length()){
            if(i+1<p.length() && p.charAt(i+1)=='*'){
                Node n1=new Node();
                Node n2=new Node();
                pre.addEdge(new Edge(null,n1));
                pre.addEdge(new Edge(null,n2));
                n1.addEdge(new Edge(p.charAt(i),n1));
                n1.addEdge(new Edge(p.charAt(i),n2));
                pre=n2;
                i+=2;
            }
            else{
                Node n=new Node();
                pre.addEdge(new Edge(p.charAt(i),n));
                pre=n;
                i++;
            }
        }
        pre.isEnd=true;

        //----------walking DFA-------------

        return walk(start,0);
    }

    private boolean walk(Node n,int begin){
        if(begin==input.length()){
            if(n.isEnd) return true;
            else if(n.edges.size()==0) return false;
        } 

        for(Edge e:n.edges){
            if(e.take==null) {if(walk(e.to,begin)) return true;}
            else if(begin<input.length() && e.take=='.') {if(walk(e.to,begin+1)) return true;}
            else{
                if(begin<input.length() && e.take==input.charAt(begin)) {if(walk(e.to,begin+1)) return true;}
                else continue;
            }
        }
        return false;
    }

    //-------------below are just some datastruct to implement DFA-------------

    private class Node{
        List<Edge> edges;
        boolean isEnd;

        Node(){
            edges=new ArrayList<Edge>();
        }

        void addEdge(Edge e){
            this.edges.add(e);
        }
    }

    private class Edge{
        Character take;
        Node to;

        Edge(Character c,Node n){
            this.take=c;
            this.to=n;
        }
    }
}

 

posted @ 2015-06-24 22:03  疾风剑  阅读(193)  评论(0编辑  收藏  举报