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
原创粉丝点击