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.
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; } } }