leetcode 10. Regular Expression Matching
字符串匹配问题;
1、用暴力的方法解决。
通过搜索的方式,将每一种可能都列出来;
a*或.*的时候,分三路:1、s中没有匹配到,p直接右移两位继续递归搜索;2、s中有匹配到一个a,s右移一位,p右移两位继续递归搜索;3、s中有匹配到一个,p继续用a*继续匹配s接下去的字符,则s右移一位,p不右移继续递归搜索。
只有a或者.的时候,s和p有匹配到,两个都右移一位递归搜索;

bool Match(const string& s, int s_i, const string& p, int p_i) { while (p.length() < p_i && p[p_i] == '*') ++p_i; if (s.length() == s_i && p.length() == p_i) return true; else if (s.length() != s_i && p.length() == p_i) return false; if (p_i + 1 < p.length()) { if (p[p_i+1] == '*') { if (Match(s, s_i, p, p_i + 2)) return true; if (s.length() > s_i && (s[s_i] == p[p_i] || p[p_i] == '.')) { if (Match(s, s_i+1, p, p_i + 2)) return true; if (Match(s, s_i+1, p, p_i)) return true; } } else { if (s.length() > s_i && (s[s_i] == p[p_i] || p[p_i] == '.')) { if (Match(s, s_i+1, p, p_i + 1)) return true; } } } else { if (s.length() > s_i && (s[s_i] == p[p_i] || p[p_i] == '.')) { if (Match(s, s_i+1, p, p_i + 1)) return true; } } return false; }
通过搜索发现,当前的搜索结果跟之前字符的搜索结果是有关系的;
当p+1 == a*的时候;即可以匹配0~n个相同的数;所以当匹配0个的时候: f(s+1,p) = f(s,p); 当匹配n=1个的时候: f(s+1,p + 1) = f(s,p) 又因为a*也符合f(s+1,p+1) = f(s+1,p); 当匹配n>1个的时候,则f(s,p+1)是匹配的,那么也应该符合f(s+1,p+1) = f(s,p+1),假设aa 跟a*应该是匹配的;
所以f(s+1,p+1) = f(s+1, p) | f(s,p) | f(s,p+1)
当p+1 == a的时候,则只有 f(s+1,p+1) = f(s,p)

bool DP(const string& s, const string& p) { vector<bool> arr(s.length()+1, false); arr[0] = true; int p_i = 0; while (p_i < p.length()) { while (p_i < p.length() && p[p_i] == '*') ++p_i; if (p_i == p.length()) break; if (p_i + 1 < p.length()) { if (p[p_i+1] == '*') { bool cur = arr[0]; bool mid = cur; for (int i = 0; i < s.length(); ++i) { mid = cur; cur = arr[i+1]; if (p[p_i] == s[i] || p[p_i] == '.') { arr[i + 1] = mid | arr[i] | arr[i+1]; } } ++p_i; } else { bool cur = arr[0]; for (int i = 0; i < s.length(); ++i) { if (p[p_i] == s[i] || p[p_i] == '.') { bool mid = cur; cur = arr[i+1]; arr[i+1] = mid; } else { cur = arr[i+1]; arr[i+1] = false; } } arr[0] = false; } } else { bool cur = arr[0]; for (int i = 0; i < s.length(); ++i) { if (p[p_i] == s[i] || p[p_i] == '.') { bool mid = cur; cur = arr[i+1]; arr[i+1] = mid; } else { cur = arr[i+1]; arr[i+1] = false; } } arr[0] = false; } ++p_i; // for (int i = 0; i < arr.size(); ++i) // cout << arr[i] << " "; // cout << endl; } return arr[s.length()]; }
在代码中看到有一个可以操作的比较巧妙的地方:
原本的 bool cur = arr[0]; for (int i = 0; i < s.length(); ++i) { if (p[p_i] == s[i] || p[p_i] == '.') { bool mid = cur; cur = arr[i+1]; arr[i+1] = mid; } else { cur = arr[i+1]; arr[i+1] = false; } } 改进后的 for (int i = s.length() - 1; i >= 0; --i) { if (p[p_i] == s[i] || p[p_i] == '.') { arr[i+1] = arr[i]; } else { arr[i+1] = false; } }
通过逆序的方式可以不需要记住原先的值;
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!