【动态规划】C++算法:44 通配符匹配

news2024/9/21 19:00:09

作者推荐

【动态规划】【字符串】扰乱字符串

本文涉及的基础知识点

动态规划

LeetCode44 通配符匹配

给你一个输入字符串 (s) 和一个字符模式 § ,请你实现一个支持 ‘?’ 和 ‘’ 匹配规则的通配符匹配:
‘?’ 可以匹配任何单个字符。
'
’ 可以匹配任意字符序列(包括空字符序列)。
判定匹配成功的充要条件是:字符模式必须能够 完全匹配 输入字符串(而不是部分匹配)。
示例 1:
输入:s = “aa”, p = “a”
输出:false
解释:“a” 无法匹配 “aa” 整个字符串。
示例 2:
输入:s = “aa”, p = ""
输出:true
解释:'
’ 可以匹配任意字符串。
示例 3:
输入:s = “cb”, p = “?a”
输出:false
解释:‘?’ 可以匹配 ‘c’, 但第二个 ‘a’ 无法匹配 ‘b’。
参数范围
0 <= s.length, p.length <= 2000
s 仅由小写英文字母组成
p 仅由小写英文字母、‘?’ 或 ‘*’ 组成

动态规划

共有mn种状态,故空间复杂度是O(nm),每种状态的转移时间复杂度是O(1),故时间复杂度是O(nm)。m和n是p和s的长度。

动态规划的状态表示dp[i][j]等于p[0,i)和s[0,j)是否匹配
动态规划的转移方程下文详细列出
动态规划的初始状态除dp[0][0]=true外,全部false
动态规划的填表顺序一,如果p[0,j)全部是*,则dp[j][0]=true。二, i,j全部从小到大。由短到长处理子字符串,确保动态规划的无后效性
动态规划的返回值dp[m][n]

转移方程

p[i-1]为*: a,不匹配任字符。b,匹配1到多个字符。匹配2个字符和匹配1个字符完全相同。
为? : 和dp[i-1][j-1]相同。
其它字符: p[i-1]==s[j-1] 且 dp[i-1][j-1]

代码

核心代码

class Solution {
public:
	bool isMatch(string s, string p) {
		const int m = p.length();
		const int n = s.length();
		vector<vector<bool>> dp(m + 1, vector<bool>(n + 1));
		dp[0][0] = true;
		for (int i = 0; (i < m)&&('*'==p[i]); i++)
		{
			dp[i + 1][0] = true;//p前面的*不匹配任何字符
		}
		for (int i = 1; i <= m; i++)
		{
			const char& ch = p[i - 1];
			for (int j = 1; j <= n; j++)
			{
				if ('*' == ch)
				{
					const bool b1 = dp[i - 1][j];//*不匹配任何字符
					const bool b2 = dp[i][j - 1];//*匹配字符1到x个字符
					dp[i][j] = b1 || b2;
				}
				else if ('?' == ch)
				{
					dp[i][j] =  dp[i - 1][j - 1];
				}
				else
				{
					dp[i][j] = dp[i - 1][j - 1]&&(ch == s[j-1]);
				}
			}
		}
		return dp.back().back();
	}
};

测试用例

template<class T>
void Assert(const T& t1, const T& t2)
{
	assert(t1 == t2);
}

template<class T>
void Assert(const vector<T>& v1, const vector<T>& v2)
{
	if (v1.size() != v2.size())
	{
		assert(false);
		return;
	}
	for (int i = 0; i < v1.size(); i++)
	{
		Assert(v1[i], v2[i]);
	}
}


int main()
{
	string s,p;	
	{
		Solution sln;
		s = "ab", p = "?*";
		auto res = sln.isMatch(s, p);
		Assert(true, res);
	}
	{
		Solution sln;
		s = "aa", p = "a";
		auto res = sln.isMatch(s, p);
		Assert(false, res);
	}
	
	{
		Solution sln;
		s = "aa", p = "*";
		auto res = sln.isMatch(s, p);
		Assert(true, res);
	}

	{
		Solution sln;
		s = "cb", p = "?a";
		auto res = sln.isMatch(s, p);
		Assert(false, res);
	}

}

2022 年12月

class Solution {
public:
bool isMatch(string s, string p) {
unordered_set preDp;
preDp.insert(0);
for (const auto& ch : p )
{
unordered_set dp;
if (‘*’ == ch)
{
int iMin = *std::min_element(preDp.begin(), preDp.end());
for (; iMin <= s.length(); iMin++)
{
dp.insert(iMin);
}
}
else
{
for (const auto& pre : preDp)
{
if (pre < s.length())
{
if ((‘?’ == ch) || (ch == s[pre]))
{
dp.insert(pre + 1);
}
}
}
}
preDp.swap(dp);
if (preDp.empty())
{
return false;
}
}
return *std::max_element(preDp.begin(),preDp.end()) >= s.length();
}
};

23年8月

class Solution {
public:
bool isMatch(string s, string p) {
if (p.empty())
{
return s.empty();
}
vector vp;
int left = 0;
for (int i = 0; i < p.length()😉
{
while ((i < p.length()) && (‘’ != p[i]))
{
i++;
}
//p[i]为’\0’或

vp.emplace_back(p.substr(left, i - left));
while ((i < p.length()) && (’’ == p[i]))
{
i++;
}
left = i;
}
if ('
’ == p.back())
{
vp.emplace_back(“”);
}
if (1 == vp.size())
{
return (s.length()p.length())&& (0Cmp(s,p));
}
const int iFirstLen = vp.front().length();
if (s.length() < iFirstLen)
{
return false;
}
if (0 != Cmp( s, vp.front()))
{
return false;
}
s = s.substr(iFirstLen);
vp.erase(vp.begin(), vp.begin()+1);
const int iRemain = s.length() - vp.back().length();
if (iRemain < 0)
{
return false;
}
if (0 != Cmp(s.substr(iRemain), vp.back()))
{
return false;
}
s = s.substr(0, iRemain);
vp.pop_back();
for (const auto& subP : vp)
{
const int ind = Cmp(s, subP);
if (-1 == ind)
{
return false;
}
s = s.substr(ind + subP.length());
}
return true;
}
int Cmp( const string& s , const string& strP)
{
int len = strP.length();
for (int i = 0; i+len <= s.length(); i++)
{
if (CmpInner(s, i, strP))
{
return i;
}
}
return -1;
}
bool CmpInner(const string& s,int si, const string& strP)
{
int len = strP.length();
for (int i = 0; i < len; i++)
{
if ((s[i+si] != strP[i]) && (‘?’ != strP[i]))
{
return false;
}
}
return true;
}

};

扩展阅读

视频课程

有效学习:明确的目标 及时的反馈 拉伸区(难度合适),可以先学简单的课程,请移步CSDN学院,听白银讲师(也就是鄙人)的讲解。
https://edu.csdn.net/course/detail/38771

如何你想快

速形成战斗了,为老板分忧,请学习C#入职培训、C++入职培训等课程
https://edu.csdn.net/lecturer/6176

相关下载

想高屋建瓴的学习算法,请下载《喜缺全书算法册》doc版
https://download.csdn.net/download/he_zhidan/88348653

我想对大家说的话
闻缺陷则喜是一个美好的愿望,早发现问题,早修改问题,给老板节约钱。
子墨子言之:事无终始,无务多业。也就是我们常说的专业的人做专业的事。
如果程序是一条龙,那算法就是他的是睛

测试环境

操作系统:win7 开发环境: VS2019 C++17
或者 操作系统:win10 开发环境: VS2022 C++17
如无特殊说明,本算法用**C++**实现。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1354190.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

动手学深度学习之卷积神经网络之池化层

池化层 卷积层对位置太敏感了&#xff0c;可能一点点变化就会导致输出的变化&#xff0c;这时候就需要池化层了&#xff0c;池化层的主要作用就是缓解卷积层对位置的敏感性 二维最大池化 这里有一个窗口&#xff0c;来滑动&#xff0c;每次我们将窗口中最大的值给拿出来 还是上…

大创项目推荐 深度学习人脸表情识别算法 - opencv python 机器视觉

文章目录 0 前言1 技术介绍1.1 技术概括1.2 目前表情识别实现技术 2 实现效果3 深度学习表情识别实现过程3.1 网络架构3.2 数据3.3 实现流程3.4 部分实现代码 4 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 深度学习人脸表情识别系…

【JavaFX】JavaFX11开发踩坑记录

文章目录 技术栈踩坑记录 技术栈 JavaFX 11MavenJDK 11 踩坑记录 这些坑对于初学者很容易踩&#xff0c;JavaFX经常会报错空指针异常遇到其中一个问题可能就会消耗好几天的时间。 JavaFX 采用的是MVC架构设计&#xff0c;页面设计使用 fxml文件&#xff1b;业务逻辑采用Con…

k8s的网络

k8s的网络 k8s中的通信模式&#xff1a; 1、pod内部之间容器与容器之间的通信 在同一个pod中的容器共享资源和网络&#xff0c;使用同一个网络命名空间&#xff0c;可以直接通信的 2、同一个node节点之内&#xff0c;不同pod之间的通信 每个pod都有一个全局的真实的ip地址…

qt 异常汇总

1. C2338 No Q_OBJECT in the class with the signal (编译源文件 ..\..\qt\labelme-master\src\mainwindow.cpp mainwindow头文件中的类没有Q_OBJECT宏定义&#xff0c;或者其子类或者其他依赖没有Q_OBJECT宏定义。 全部qt类都要写上Q_OBJECT. 2. C2385 对connect的访…

AI:116-基于深度学习的视频行为识别与分析

🚀点击这里跳转到本专栏,可查阅专栏顶置最新的指南宝典~ 🎉🎊🎉 你的技术旅程将在这里启航! 从基础到实践,深入学习。无论你是初学者还是经验丰富的老手,对于本专栏案例和项目实践都有参考学习意义。 ✨✨✨ 每一个案例都附带有在本地跑过的关键代码,详细讲解供…

ctfshow——PHP特性

文章目录 web 89web 90web 91web 92web 93web 94web 95web 96web 97web 98web 99 web 89 使用人工分配 ID 键的数值型数组绕过preg_match. 两个函数&#xff1a; preg_match()&#xff1a;执行正则表达式&#xff0c;进行字符串过滤。preg_match函数用法&#xff0c;正则表达式…

uni-app 前后端调用实例 基于Springboot 详情页实现

锋哥原创的uni-app视频教程&#xff1a; 2023版uniapp从入门到上天视频教程(Java后端无废话版)&#xff0c;火爆更新中..._哔哩哔哩_bilibili2023版uniapp从入门到上天视频教程(Java后端无废话版)&#xff0c;火爆更新中...共计23条视频&#xff0c;包括&#xff1a;第1讲 uni…

【Java EE初阶七】多线程案例(生产者消费者模型)

1. 阻塞队列 队列是先进先出的一种数据结构&#xff1b; 阻塞队列&#xff0c;是基于队列&#xff0c;做了一些扩展&#xff0c;适用于多线程编程中&#xff1b; 阻塞队列特点如下&#xff1a; 1、是线程安全的 2、具有阻塞的特性 2.1、当队列满了时&#xff0c;就不能往队列里…

Yapi安装配置(CentOs)

环境要求 nodejs&#xff08;7.6) mongodb&#xff08;2.6&#xff09; git 准备工作 清除yum命令缓存 sudo yum clean all卸载低版本nodejs yum remove nodejs npm -y安装nodejs,获取资源,安装高版本nodejs curl -sL https://rpm.nodesource.com/setup_8.x | bash - #安装 s…

图片中src属性绑定不同的路径

vue3 需求是按钮disable的时候&#xff0c;显示灰色的icon&#xff1b;非disable状态&#xff0c;显示白色的icon 一开始src写成三元表达式&#xff0c;发现不行&#xff0c;网上说src不能写成三元表达式&#xff0c;vue会识别成字符串 最后的解决方案 同时&#xff0c;发现…

win下持续观察nvidia-smi

简介&#xff1a;在Windows操作系统中&#xff0c;没有与Linux中watch命令直接对应的内置工具&#xff0c;但有1种方法快速简单的方法可以实现类似的效果&#xff0c;尤其是用于监控类似于nvidia-smi的命令输出。 历史攻略&#xff1a; Python&#xff1a;查看windows下GPU的…

美国地质调查局历史地形图

简介 美国地质调查局地形图的历史可以追溯到 19 世纪末&#xff0c;当时美国地质调查局开始着手绘制整个美国的详细地图。1:24,000 比例尺&#xff0c;也称为 7.5 分四边形地图&#xff0c;成为最广泛使用的比例尺之一。每张地图覆盖 7.5 分经纬度的区域&#xff0c;从而详细呈…

在Docker中安装Tomact

目录 前言&#xff1a; 一.安装Tomact 查找指定的tomact版本 下载tomact9.0 查看该镜像是否安装成功 安装成功之后就开始运行镜像了 ps&#xff08;用于列出正在运行的Docker容器&#xff09; ​编辑 测试(虚拟机ip:8080) ​编辑 解决措施 ​编辑 完成以上步骤&…

【Nginx】反向代理和负载均衡

反向代理 nginx 反向代理&#xff0c;就是将前端发送的动态请求由 nginx 转发到后端服务器。 server {listen 80;server_name localhost;# 反向代理,处理管理端发送的请求location /api/ {proxy_pass http://localhost:8080/admin/;#proxy_pass http://webservers/…

【Electron】快速建立Vue3+Vite+Electron Ts项目

git https://github.com/electron-vite/electron-vite-vue 创建项目 npm create electron-vite or pnpm create electron-vite 初始化 pnpm install or pnpm i 启动项目 pnpm dev 打包项目 pnpm build 项目创建成功后默认情况下 窗口是H800 W600 在createWindow 函数…

计算机视觉中的神经网络可视化工具与项目

前言 本文介绍了一些关于神经网络可视化的项目&#xff0c;主要有CNN解释器&#xff0c;特征图、卷积核、类可视化的一些代码和项目&#xff0c;结构可视化工具&#xff0c;网络结构手动画图工具。 CNN解释器 这是一个中国博士发布的名叫CNN解释器的在线交互可视化工具。 主要…

macOS跨进程通信: FIFO(有名管道) 创建实例

一&#xff1a; 简介 在类linux系统中管道分为有名管道和匿名管道。两者都能单方向的跨进程通信。 匿名管道&#xff08;pipe&#xff09;: 必须是父子进程之间&#xff0c;而且子进程只能由父进程fork() 出来的&#xff0c;才能继承父进程的管道句柄&#xff0c;一般mac 开发…

基于多反应堆的高并发服务器【C/C++/Reactor】(中)子线程 WorkerThread的实现 和 线程池ThreadPool的初始化

一、子线程 WorkerThread的实现 &#xff08;1&#xff09;工作线程 线程ID&#xff1a;每个线程都有一个唯一的ID,用于标识线程的名字&#xff1a;非必需&#xff0c;主要用于识别线程互斥锁&#xff1a;线程同步条件变量&#xff1a;线程阻塞EventLoop&#xff1a;在每个子…

WEB:探索开源PDF.js技术应用

1、简述 PDF.js 是一个由 Mozilla 开发的开源 JavaScript 库&#xff0c;用于在浏览器中渲染 PDF 文档。它的目标是提供一个纯粹的前端解决方案&#xff0c;摆脱了依赖插件或外部程序的束缚&#xff0c;使得在任何支持 JavaScript 的浏览器中都可以轻松地显示 PDF 文档。 2、…