10. Regular Expression Matching
来源:互联网 发布:人类快感分级 知乎 编辑:程序博客网 时间:2024/04/27 06:52
我没使用DP,刚刚好想起了之前看黄色算法的正则表达式,于是灵光一闪,想用构造NFA和图遍历的方法来解这道题,好吧感觉就是抄了一遍算法书构造了图,和书上代码基本类似,ac这道题画了17ms,理了一下思路:代码放下
import java.util.LinkedList;import java.util.Stack;public class RegularExpressionMatching { public RegularExpressionMatching() { // TODO Auto-generated constructor stub } public boolean isMatch(String s, String p) { NFA nfa = new NFA(p); return nfa.recognizes(s); }}class Digraph{ private final int V; private int E; private LinkedList<Integer>[] adj; public Digraph(int V){ this.V =V; this.E = 0; adj = new LinkedList[V]; for(int v=0;v<V;v++){ adj[v] = new LinkedList<>(); } } public int V(){ return V; } public int E(){ return E; } public void addEdge(int v,int w){ adj[v].add(w); E++; } public Iterable<Integer> adj(int v){ return adj[v]; } public Digraph reverse(){ Digraph R = new Digraph(V); for (int v = 0; v < V; v++) { for(int w:adj[v]){ addEdge(w, v); } } return R; }}class DirectedDFS{//算法4.4 4.2.3 private boolean[] marked; public DirectedDFS(Digraph G,int s){ marked = new boolean[G.V()]; dfs(G,s); } public DirectedDFS(Digraph G,Iterable<Integer> sources){ marked = new boolean[G.V()]; for(int s:sources) if(!marked[s])dfs(G,s); } private void dfs(Digraph G,int v){ marked[v] = true; for(int w:G.adj(v)){ if(!marked[w]){ dfs(G,w); } } } public boolean marked(int w){ return marked[w]; }}class NFA{ private char[] re; private Digraph G; private int M; public NFA(String regexp){ Stack<Integer> ops = new Stack<Integer>(); re = regexp.toCharArray(); M =re.length; G = new Digraph(M+1); for(int i=0;i<M;i++){ int lp=i; if(re[i] == '('||re[i] == '|') ops.push(i); else if(re[i] == ')'){ int or = ops.pop(); if(re[or] == '|'){ lp = ops.pop(); G.addEdge(lp, or+1); G.addEdge(or, i); } else lp=or; } if(i<M-1&&re[i+1] == '*'){ G.addEdge(lp, i+1); G.addEdge(i+1, lp); } if(re[i] == '('||re[i]=='*'||re[i]==')'){ G.addEdge(i, i+1); } } } public boolean recognizes(String txt){ LinkedList<Integer> pc = new LinkedList<>(); DirectedDFS dfs = new DirectedDFS(G, 0); for (int v = 0; v <G.V(); v++) { if(dfs.marked(v))pc.add(v); } for(int i =0;i<txt.length();i++){ LinkedList<Integer> match = new LinkedList<>(); for(int v:pc){ if(v<M){ if(re[v] == txt.charAt(i)||re[v] =='.') match.add(v+1); } } pc = new LinkedList<>(); dfs = new DirectedDFS(G, match); for(int v=0;v<G.V();v++){ if(dfs.marked(v))pc.add(v); } } for(int v:pc)if(v==M) return true; return false; }}
0 0
- 10. Regular Expression Matching
- 10.Regular Expression Matching
- 10. Regular Expression Matching
- 10. Regular Expression Matching
- 10. Regular Expression Matching
- 10. Regular Expression Matching
- 10. Regular Expression Matching
- 10. Regular Expression Matching
- 10. Regular Expression Matching
- 10. Regular Expression Matching
- 10. Regular Expression Matching
- 10. Regular Expression Matching
- 10. Regular Expression Matching
- 10. Regular Expression Matching
- 10. Regular Expression Matching
- 10. Regular Expression Matching
- 10. Regular Expression Matching
- 10. Regular Expression Matching
- CheckIO House Password
- Android :“万能” Activity 重构篇(上)
- 应用的相互跳转
- 文章标题
- WebView你真的熟悉吗
- 10. Regular Expression Matching
- Android :“万能” Activity 重构篇(下)
- HTTP1.0和HTTP1.1区别及http状态码
- 【RFC】接口小结
- html头文件<meta>设置缓存
- AFNetWorking的两个使用场景(请求网络数据、图片上传)
- 做朋友圈的界面 cell的高度的动态调节1
- 多表连接中对应的javabean-UserEntity
- 如何调试 Android Framework?