Princeton Algorithms: Part 2 [week 6: Regular Expressions]

前端之家收集整理的这篇文章主要介绍了Princeton Algorithms: Part 2 [week 6: Regular Expressions]前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

Exercise




Question Explanation

  1. The correct answer is: 6 7 8

    Here are the sets of reachable states after reading in the first i characters
    (and following epsilon-transitions):

    i substring set of reachable states
    ------------------------------------------------
    0 0 1
    1 B 2 3 5 6 7 8 11 12 13
    2 B A 2 3 4 5 6 7 8 9 10 11 12 13
    3 B A A 2 3 4 5 6 7 8 9 10 11 12 13
    4 B A A A 2 3 4 5 6 7 8 9 10 11 12 13
    5 B A A A C 6 7 8
    6 B A A A C C 6 7 8



Here are all of the edges in the epsilon-transition digraph:
0-> 1
0-> 3
2->10
3-> 4
3-> 9
5-> 6
6-> 5
6-> 7
8-> 9
9-> 3
9->10
10->11


Interview Questions




  1. /*************************************************************************
  2. * Compilation: javac NFA.java
  3. * Execution: java NFA regexp text
  4. * Dependencies: Stack.java Bag.java Digraph.java DirectedDFS.java
  5. *
  6. * % java NFA "(A*B|AC)D" AAAABD
  7. * true
  8. *
  9. * % java NFA "(A*B|AC)D" AAAAC
  10. * false
  11. *
  12. * % java NFA "(a|(bc)*d)*" abcbcd
  13. * true
  14. *
  15. * % java NFA "(a|(bc)*d)*" abcbcbcdaaaabcbcdaaaddd
  16. * true
  17. *
  18. * Remarks
  19. * -----------
  20. * - This version does not suport the + operator or multiway-or.
  21. *
  22. * - This version does not handle character classes,* Metacharacters (either in the text or pattern),capturing
  23. * capabilities,greedy vs. relucantant modifier,and
  24. * other features in industrial-strength implementations such
  25. * as java.util.regexp.
  26. *
  27. *************************************************************************/
  28.  
  29. public class NFA {
  30.  
  31. private Digraph G; // digraph of epsilon transitions
  32. private String regexp; // regular expression
  33. private int M; // number of characters in regular expression
  34.  
  35. // Create the NFA for the given RE
  36. public NFA(String regexp) {
  37. this.regexp = regexp;
  38. M = regexp.length();
  39. Stack<Integer> ops = new Stack<Integer>();
  40. G = new Digraph(M+1);
  41. for (int i = 0; i < M; i++) {
  42. int lp = i;
  43. if (regexp.charAt(i) == '(' || regexp.charAt(i) == '|')
  44. ops.push(i);
  45. else if (regexp.charAt(i) == ')') {
  46. int or = ops.pop();
  47.  
  48. // 2-way or operator
  49. if (regexp.charAt(or) == '|') {
  50. lp = ops.pop();
  51. G.addEdge(lp,or+1);
  52. G.addEdge(or,i);
  53. }
  54. else if (regexp.charAt(or) == '(')
  55. lp = or;
  56. else assert false;
  57. }
  58.  
  59. // closure operator (uses 1-character lookahead)
  60. if (i < M-1 && regexp.charAt(i+1) == '*') {
  61. G.addEdge(lp,i+1);
  62. G.addEdge(i+1,lp);
  63. }
  64. if (regexp.charAt(i) == '(' || regexp.charAt(i) == '*' || regexp.charAt(i) == ')')
  65. G.addEdge(i,i+1);
  66. }
  67. }
  68.  
  69. // Does the NFA recognize txt?
  70. public boolean recognizes(String txt) {
  71. DirectedDFS dfs = new DirectedDFS(G,0);
  72. Bag<Integer> pc = new Bag<Integer>();
  73. for (int v = 0; v < G.V(); v++)
  74. if (dfs.marked(v)) pc.add(v);
  75.  
  76. // Compute possible NFA states for txt[i+1]
  77. for (int i = 0; i < txt.length(); i++) {
  78. Bag<Integer> match = new Bag<Integer>();
  79. for (int v : pc) {
  80. if (v == M) continue;
  81. if ((regexp.charAt(v) == txt.charAt(i)) || regexp.charAt(v) == '.')
  82. match.add(v+1);
  83. }
  84. dfs = new DirectedDFS(G,match);
  85. pc = new Bag<Integer>();
  86. for (int v = 0; v < G.V(); v++)
  87. if (dfs.marked(v)) pc.add(v);
  88.  
  89. // optimization if no states reachable
  90. if (pc.size() == 0) return false;
  91. }
  92.  
  93. // check for accept state
  94. for (int v : pc)
  95. if (v == M) return true;
  96. return false;
  97. }
  98.  
  99.  
  100. public static void main(String[] args) {
  101. String regexp = "(" + args[0] + ")";
  102. String txt = args[1];
  103. if (txt.indexOf('|') >= 0) {
  104. throw new IllegalArgumentException("| character in text is not supported");
  105. }
  106. NFA nfa = new NFA(regexp);
  107. StdOut.println(nfa.recognizes(txt));
  108. }
  109.  
  110. }

猜你在找的正则表达式相关文章