/** * Returns true if the text is matched by the regular expression. * * @param txt the text * @return {@code true} if the text is matched by the regular expression, * {@code false} otherwise */ public boolean recognizes(String txt) { DirectedDFS dfs = new DirectedDFS(graph, 0); Bag<Integer> pc = new Bag<Integer>(); for (int v = 0; v < graph.V(); v++) if (dfs.marked(v)) pc.add(v); // Compute possible NFA states for txt[i+1] for (int i = 0; i < txt.length(); i++) { if (txt.charAt(i) == '*' || txt.charAt(i) == '|' || txt.charAt(i) == '(' || txt.charAt(i) == ')') throw new IllegalArgumentException("text contains the metacharacter '" + txt.charAt(i) + "'"); Bag<Integer> match = new Bag<Integer>(); for (int v : pc) { if (v == m) continue; if ((regexp.charAt(v) == txt.charAt(i)) || regexp.charAt(v) == '.') match.add(v+1); } dfs = new DirectedDFS(graph, match); pc = new Bag<Integer>(); for (int v = 0; v < graph.V(); v++) if (dfs.marked(v)) pc.add(v); // optimization if no states reachable if (pc.size() == 0) return false; } // check for accept state for (int v : pc) if (v == m) return true; return false; }
/** * Unit tests the {@code DirectedDFS} data type. * * @param args the command-line arguments */ public static void main(String[] args) { // read in digraph from command-line argument In in = new In(args[0]); Digraph G = new Digraph(in); // read in sources from command-line arguments Bag<Integer> sources = new Bag<Integer>(); for (int i = 1; i < args.length; i++) { int s = Integer.parseInt(args[i]); sources.add(s); } // multiple-source reachability DirectedDFS dfs = new DirectedDFS(G, sources); // print out vertices reachable from sources for (int v = 0; v < G.V(); v++) { if (dfs.marked(v)) StdOut.print(v + " "); } StdOut.println(); }
private DirectedDFS[] tc; // tc[v] = reachable from v /** * Computes the transitive closure of the digraph {@code G}. * @param G the digraph */ public TransitiveClosure(Digraph G) { tc = new DirectedDFS[G.V()]; for (int v = 0; v < G.V(); v++) tc[v] = new DirectedDFS(G, v); }