传送门:https://leetcode-cn.com/problems/regular-expression-matching/

题目

给你一个字符串s和一个字符规律p,请你来实现一个支持'.''*'的正则表达式匹配。

'.' :匹配任意单个字符 '*' :匹配零个或多个前面的那一个元素 所谓匹配,是要涵盖整个字符串s的,而不是部分字符串。

示例 1:

输入:s = “aa” p = “a” 输出:false 解释:”a” 无法匹配 “aa” 整个字符串。


示例 2:**

输入:s = “aa” p = “a“ 输出:true 解释:因为 ‘‘ 代表可以匹配零个或多个前面的那一个元素, 在这里前面的元素就是 ‘a’。因此,字符串 “aa” 可被视为 ‘a’ 重复了一次。


示例 3:**

输入:s = “ab” p = “.“ 输出:true 解释:”.“ 表示可匹配零个或多个(’*’)任意字符(’.’)。


示例 4:**

输入:s = “aab” p = “cab” 输出:true 解释:因为 ‘*’ 表示零个或多个,这里 ‘c’ 为 0 个, ‘a’ 被重复一次。因此可以匹配字符串 “aab”。

示例 5:

输入:s = “mississippi” p = “misisp*.” 输出:false

阿巴阿巴 ….大家好,我是老实巴交的老实人,得知大家都用动态规划做的我人傻了。

代码

我的代码

  1. class Solution {
  2. public:
  3. bool clearOne(string p) {//空串返回false
  4. int p_len = p.length();
  5. int pp = 0;
  6. if (p.empty() || p == "")return false;
  7. if (((pp + 1) < p.length()) && (p.at(pp + 1) == '*')) return true;
  8. return false;
  9. }
  10. bool check_pnull(string p) {//判断规则p剩余部分是否可以抵消
  11. int p_len = p.length();
  12. int pp = 0;
  13. if (p.empty() || p == "")return true;
  14. while (pp < p_len) {//字母在
  15. if (pp + 1 < p_len) {//*号在
  16. if (p.at(pp + 1) == '*')//*匹配
  17. pp += 2;
  18. else
  19. return false;
  20. }
  21. else {//*号不在
  22. if (p.at(pp) == '*')
  23. return true;
  24. return false;
  25. }
  26. }
  27. return true;
  28. }
  29. bool isMatch(string s, string p) {
  30. int s_len = s.length();
  31. int p_len = p.length();//二者长度
  32. int sp, pp;//哨兵
  33. sp = pp = 0;//初始化
  34. if ((!s.empty()) && (p.empty() || p == ""))return false;
  35. if (!p.empty() && (s.empty() || s == "")) {
  36. if (check_pnull(p))return true;
  37. return false;
  38. }//去除非法情况和特殊空串情况
  39. while (sp < s_len || pp < p_len) {
  40. while ((sp < s_len && pp < p_len) && s.at(sp) == p.at(pp)) {//二者相等就顺着排
  41. sp++; pp++;
  42. }//匹配就下行
  43. //出来有可能是不匹配也有可能是超过长度
  44. //1不匹配
  45. if (sp < s_len && pp < p_len) {//确保在长度内
  46. if (p.at(pp) == '.') {//.类型不匹配
  47. sp++; pp++;
  48. }
  49. else if (p.at(pp) == '*') {//*类型不匹配
  50. bool real = false;
  51. int temp_sp = sp - 1;
  52. //第一种先消去*前面的来跟s匹配
  53. if (pp + 1 < p_len)//未越界情况才有可能消去,越界一定不用消除
  54. real= isMatch(s.substr(temp_sp, s_len - temp_sp), p.substr(pp + 1, p_len - pp - 1));
  55. if (real)return true;
  56. //第二种到底匹配几个的问题
  57. if ((sp < s_len && pp + 1 < p_len)) {//*只匹配一次
  58. real = isMatch(s.substr(sp, s_len - sp), p.substr(pp + 1, p_len - pp - 1));
  59. if (real)return true;
  60. }
  61. while ((sp < s_len && pp < p_len)) {//从第2此开始依次匹配
  62. if ((s.at(sp) == p.at(pp - 1)) || p.at(pp - 1) == '.') {
  63. sp++;
  64. if ((sp < s_len && pp + 1 < p_len)) {
  65. real = isMatch(s.substr(sp, s_len - sp), p.substr(pp + 1, p_len - pp - 1));
  66. if (real)return true;
  67. }
  68. }
  69. else {
  70. pp++;
  71. break;
  72. }
  73. }
  74. // pp++;
  75. }
  76. else {
  77. if ((pp + 1 < p_len) && (p.at(pp + 1) == '*')) {//还有救
  78. pp += 2;
  79. }
  80. else
  81. return false;
  82. }
  83. }
  84. else {//2超出长度
  85. //如果二者同时超出了长度则说明匹配成功
  86. //若是单独一方超出则要看情况
  87. //a. 若p超出了长度,说明s串还有未比配的数,一定不匹配
  88. //b. 若s超出了长度,说明要回溯,两种检查,剩下p是否能check_pnull,若能则匹配,若不能则claenOne弄掉一对让s的最后一个字母与剩下的p规则匹配
  89. if (sp == s_len && pp == p_len) {//二者同时超出了长度则说明匹配成功
  90. return true;
  91. }
  92. else {//单独一方超出
  93. if (pp >= p_len)return false;//a
  94. if (sp >= s_len) {//b
  95. if (p.at(pp) == '*') {
  96. if (check_pnull(p.substr(pp + 1, p_len - pp))) return true;//剩下的能消除
  97. else {//不能消除
  98. if (clearOne(p.substr(pp - 1, p_len - pp + 1))) {
  99. sp--;
  100. pp = pp + 1;
  101. return isMatch(s.substr(sp, s_len - sp), p.substr(pp, p_len - pp));
  102. }
  103. else return false;
  104. }
  105. }
  106. else {
  107. if (check_pnull(p.substr(pp, p_len - pp))) return true;//剩下的能消除
  108. else {//不能消除
  109. if (clearOne(p.substr(pp - 1, p_len - pp + 1))) {
  110. sp--;
  111. pp = pp + 1;
  112. return isMatch(s.substr(sp, s_len - sp), p.substr(pp, p_len - pp));
  113. }
  114. else return false;
  115. }
  116. }
  117. }
  118. }
  119. }
  120. }
  121. if (sp == s_len && pp == p_len)
  122. return true;
  123. else
  124. return false;
  125. }
  126. };