【优选算法 | 前缀和】前缀和算法:高效解决区间求和问题的关键
算法 | 相关知识点 | 可以通过点击 | 以下链接进行学习 | 一起加油! |
---|---|---|---|---|
双指针 | 滑动窗口 | 二分查找 |
在本篇文章中,我们将深入解析前缀和算法的原理。从基础概念到实际应用,带你了解如何通过前缀和高效解决数组求和、区间查询等问题。无论你是刚接触算法的新手,还是希望提升代码性能的老手,前缀和都是你提升算法效率的重要利器!
🌈个人主页:是店小二呀
🌈C/C++专栏:C语言\ C++
🌈初/高阶数据结构专栏: 初阶数据结构\ 高阶数据结构
🌈Linux专栏: Linux
🌈算法专栏:算法
🌈Mysql专栏:Mysql
🌈你可知:无人扶我青云志 我自踏雪至山巅
文章目录
- DP34.【模板】前缀和
- DP35.【模板】二维前缀和
- 724. 寻找数组的中心下标
- 238. 除自身以外数组的乘积
- 560. 和为 K 的子数组
- 974.和可被 K 整除的子数组
- 525. 连续数组
- 1314. 矩阵区域和
DP34.【模板】前缀和
【题目】:DP34.【模板】前缀和
示例1输入:
3 2 1 2 4 1 2 2 3
输出:
3 6
解法一:暴力解法
每次询问时,求出该区间的和以及包含多少个q,并计算其重复次数,所消耗时间复杂度O(n*q)
解法二:前缀和
前缀和是用于"快速得到某一段区间的和",所需要消耗时间复杂度为O(q+n)
第一步:预处理"前缀和数组"
- dp[i]表示:[1, i]区间内所有元素的和
- dp[i - 1]表示:[1, i - 1]区间内所有元素的和
通过arr数组和"前缀和数组"之间关系,没有必要重新遍历arr数组求和,再填写到"前缀和数组"内,其中推导出 递推公式:dp[i] = dp [i - 1] + add[i]。
预处理前缀和数组的过程,本质上就是个小的动态规划。无非就是状态标识,状态转移方程。
第二步:使用前缀和数组
使⽤前缀和数组,「快速」求出「某⼀个区间内」所有元素的和: 当询问的区间是 [l, r] 时:区间内所有元素的和为: dp[r] - dp[l - 1] 。
默认情况下,C++ 中
vector<int> dp(n + 1)
会将dp
数组的所有元素初始化为0
,因此dp[0]
也是0
。
#include <iostream>
#include <vector>
using namespace std;int main()
{//1.读取数据int n, q;cin >> n >> q;vector<int> arr(n + 1);//输入原始数组for(int i = 1; i <= n; i++) cin >> arr[i];//2.预处理出来一个前缀和数组vector<long long> dp(n + 1);//防止溢出//输入DP数组数据for(int i = 1; i <= n; i++) dp[i] = dp[i - 1] + arr[i];int l = 0, r = 0;while(q--){cin >> l >> r;cout << dp[r] - dp[l - 1] << endl;}return 0;
}
【细节问题】:为什么下标从1开始计数?
通过[0, 2]和[1,2]分析可得,dp[-1]下标是负数存在越界访问,dp[0]也需要单独赋值。不然下标1开始计算,解决了上面两个问题。
- 为了处理边界情况
- 初始化:添加虚拟节点(辅助节点)
DP35.【模板】二维前缀和
【题目】:DP35.【模板】二维前缀和
输入:
3 4 3 1 2 3 4 3 2 1 0 1 5 7 8 1 1 2 2 1 1 3 3 1 2 3 4
输出:
8 25 32
【算法思路】
解法一:暴力解法->模拟
解法二:前缀和
1.预处理出来一个前缀和矩阵
其中,我们需要知道dp[i] [j]元素表达含有,更好地去使用前缀和矩阵解决问题。
dp[i] [j]表示:从[1, 1]位置到[i, j]位置,这段区间里面所有元素的和
不理解为什么是从[1, 1]位置开始,可以结合上一道题目解析和本题数据氛围限制理解。
2.找到状态转移方程
根据 dp[i][j]
元素的含义,推导其状态转移方程,分析是否存在等价关系,或者从前状态推导出后状态。在推导过程中,要注意细节,特别是从 dp[i-1][j-1]
或者面积的组合角度入手,确保理解 dp[i][j]
的具体含义。
3.使用前缀和矩阵
细节问题:这里D面积是[x1, y1] -> [x2, y2],而对于A面积是[1, 1] -> [x1 -1, y1 - 1],注意看红色的线。
【代码实现】
#include <iostream>
using namespace std;
#include <vector>int main()
{int n = 0, m = 0, q = 0;cin >> n >> m >> q;//1.读入数据vector<vector<int>> arr(n + 1, vector<int>(m + 1));for(int i = 1; i <= n; i++)for(int j = 1;j <= m; j++)cin >> arr[i][j];//2.处理前缀和矩阵vector<vector<long long>> dp(n + 1,vector<long long>(m + 1));for(int i = 1; i <= n; i++)for(int j = 1;j <= m; j++)dp[i][j] = dp[i - 1][j] + dp[i][j - 1] + arr[i][j] - dp[i- 1][j - 1];//3.使用前缀和矩阵int x1 = 0, y1 =0, x2 = 0, y2 = 0;while(q--){cin >> x1 >> y1 >> x2 >> y2;cout << dp[x2][y2] - dp[x1 - 1][y2] - dp[x2][y1 - 1] + dp[x1 - 1][y1 - 1] <<endl;}return 0;
}
724. 寻找数组的中心下标
【题目】:724. 寻找数组的中心下标
【算法思路】
使用前缀和算法时,不能死记硬背模板,关键是理解其思想,并根据具体问题灵活调整。模板中的算法思路可以为我们提供思路,但需要根据题目微调。
对于需要快速统计某个元素之前或之后所有元素和的情况,可以分别构建前缀和矩阵和后缀和矩阵。通过图示帮助分析问题,提升理解与解决效率。
- f:前缀和数组:f[i]表示:[0, i - 1]区间,所有元素的和
- g:后缀和数组:g[i]表示:[i + 1, n - 1]区间,所有元素的和
【个人思考】:在推导状态转移方程时,首先理解当前定义的含义,并从前后元素的关系入手,逐步构建方程。举个例子,假设 f[i]
表示区间 [0, i-1]
所有元素的和,那么 f[i-1]
表示区间 [0, i-2]
的和。为了使 f[i]
满足其定义,我们需要将 nums[i-1]
加入,从而得到状态转移方程。
【细节问题】:
-
f(0) = 0,左边没有元素
-
g(0) = 0,右边没有元素
-
f:从左向右
-
g:从右向左
-
如果出现多个中心下标,[0,0,0,0] 返回最左边位置
【代码实现】:
class Solution {
public:int pivotIndex(vector<int>& nums){int n = nums.size();vector<int> f(n);vector<int> g(n);for(int i = 1; i < n; i++) f[i] = f[i - 1] + nums[i - 1];for(int i = n - 2; i >= 0; i--)g[i] = g[i + 1] + nums[i + 1];for(int i = 0; i < n; i++) if(f[i] == g[i]) return i;return -1;}
};
从下标 1 到 n-2 开始处理,因为下标 0 和 n-1 对应的数据已经特殊处理为 0,且没有实际意义。如果从下标 0 或 n-1 开始,可能会导致越界访问。
238. 除自身以外数组的乘积
【题目】:238. 除自身以外数组的乘积
【算法思路】
解法一:暴力解法
直接暴力枚举,从从前往后遍历,枚举每一个位置需要O(n),同时需要遍历每个数组,整体时间复杂度是个N方级别的
解法二:前后缀积
如果需要用到前后数据元素积,我们需要搭建前缀积矩阵与后缀积矩阵
“这个题和 ‘724. 寻找数组的中心下标’ 的算法思路非常相似,主要区别在于细节处理,尤其是临界元素的取值问题。根据 f[i] = f[i-1] + nums[i-1]
的规律,当 i = 1
时,必须设定 f[0] = 1
,以确保 f[1]
表示区间 [0, 0]
对应的原始数据 nums[0]
,因为1乘任何数都等于它本身。
在“除自身以外数组的乘积”的解法中,我们不需要计算每个元素前面和后面的乘积,而是通过前缀积 f[i]
和后缀积 g[i]
来在每个位置 i
计算出左边和右边的乘积,从而避免了除法的使用。
最终每个 output[i]
的值是 f[i] * g[i]
,这就得到了除 nums[i]
外的所有元素的乘积。
【代码实现】
class Solution {
public:vector<int> productExceptSelf(vector<int>& nums){int n = nums.size();vector<int> f(n), g(n);f[0] = g[n - 1] = 1;for(int i = 1; i < n; i++) f[i] = f[i - 1] * nums[i - 1];for(int i = n - 2; i >= 0; i--) g[i] = g[i + 1] * nums[i + 1];vector<int> ret(n);for(int i = 0; i < n; i++) ret[i] = f[i] * g[i];return ret;}
};
560. 和为 K 的子数组
【题目】:560. 和为 K 的子数组
【算法思路】
解法一:暴力枚举
如果使用暴力枚举可以解决这道问题,但是我们可以有更好的解法
解法二:前缀和 + 哈希表
返回和为 k 的子数组个数”这类问题,我们可以通过前缀和 + 哈希表来优化。一个关键的思路是“以 i 位置为结尾的所有子数组”。
实际上,问题本质上仍然是暴力枚举的思路,之前我们是“以 i 位置为开始的所有子数组”。之所以选择“以 i 位置为结尾的子数组”,是因为我们想使用“前缀和 + 哈希表”来快速求出子数组的和。通过这种方式,我们能够高效地统计子数组的次数。
如果使用“以 i 位置为开始的子数组”,我们需要从已知位置向未知位置查找,不容易统计之前出现的子数组。而“以 i 位置为结尾的子数组”则是从未知位置向已知位置查找,可以通过哈希表来快速得出子数组和,提升效率。
问题转化为前缀和,就是之前前缀和数据可以重复使用,多转一。
【魔鬼细节问题】
1.【sum[i] - k含义】
对于某个 i
位置,考虑到子数组和为 k 的问题,可以通过等价关系转化为:找出多少个前缀和等于 sum[i] - k
。这里的 sum[i] - k
不是固定值,而是动态计算得到的。通过不断更新的前缀和,我们可以找到符合条件的子数组数量,判断以 i
位置为结尾的子数组和是否等于 k。
2.【前缀和加入哈希表时机】
在计算第i个位置之前,哈希表仅保存位置[0, i-1]的前缀和。如果提前将元素加入前缀和,效果不如直接暴力枚举,且会导致哈希表统计位置时出现问题。
3.【不用真的创建一个前缀和数组】
dp[i] = dp[i - 1] + nums[i]
,这里无需额外创建前缀和数组来存储数据,哈希表负责处理前缀和。通过遍历一次前缀和并建立哈希表的映射关系即可。
4.【默认前缀和全部等于k】
哈希表在后续统计时,如果 count(x) == 0
,可能导致无法正确统计。因此,单独设置 hash[0] = 1
是为了避免这种情况。没有 hash[0] = 1
时,程序会缺少一个初始的前缀和 0
。假设某个子数组的和恰好等于 k
,且该子数组从数组的开头开始,如果没有这个初始前缀和 0
,就无法通过 hash[sum - k]
条件识别这个子数组。
【代码实现】
class Solution {
public:int subarraySum(vector<int>& nums, int k) {unordered_map<int, int> hash;int sum = 0, ret =0;hash[0] = 1; //确保第一个数for(auto x : nums){sum += x;if(hash.count(sum - k)) ret += hash[sum - k];hash[sum]++;}return ret;}
};
974.和可被 K 整除的子数组
【题目】:974. 和可被 K 整除的子数组
【算法思路】
本题算法数量同"560. 和为 K 的子数组"类似,重点在于细节处理上。
【补充知识】:同余定理
这里只需要记住结论:(a - b) / p = k ....0 -> a% p = b% p
C++,Java:[负数% 正数]的结果以及修正
本题思路:
找到在 [0, i - 1] 区间内,有多少前缀和的余数(x% k)等于 sum[i] % k 的即可
【细节问题】
1.修正后的余数:int r = (sum % k + k) % k;
2.填入哈希表时机
3.0余数处理:hash[0 % k] = 1; // 0 这个数的余数
4.不用真的创建一个前缀和数组
【代码实现】
class Solution {
public:int subarraysDivByK(vector<int>& nums, int k) {unordered_map<int, int> hash;hash[0 % k]++;int sum = 0, ret = 0;for(auto x : nums){sum += x;int r = (sum % k + k) % k;if(hash.count(r)) ret += hash[r];hash[r]++;}return ret;}
};
525. 连续数组
【题目】:525. 连续数组
【算法思路】
本题要求找出一个连续子数组,使得其中 0
和 1
的数量相等。
- 如果将
0
记为-1
,1
记为1
,问题就转化为寻找一个和为0
的子数组。 - 这个思路和 LeetCode 560 题“和为 K 的子数组”是一样的。
【细节问题】
1.【默认前缀和为0的情况】
当前缀和为 0 时,如果不做处理,无法正确计算子数组的长度。之所以设置 hash[0] = -1
,是因为在计算子数组长度时,i - j
代表的是当前位置和前一个位置的差。为了能够正确计算从数组起始位置到当前下标的子数组长度,我们默认前缀和为 0 时的下标是 -1
。
2.【哈希表存储】
hash<int_前缀和,int _下标>
3.如果有重复<sum, i>
只保留前面那一对<sum, i>
4.计算长度
【代码实现】
class Solution {
public:int findMaxLength(vector<int>& nums) {unordered_map <int, int> hash;hash[0] = -1; // 默认有⼀个前缀和为 0 的情况int sum = 0, ret = 0;for(int i = 0; i < nums.size();i++){sum += nums[i] == 0 ? -1 : 1;if(hash.count(sum)) ret = max(ret,i - hash[sum]);else hash[sum] = i;}return ret;}
};
1314. 矩阵区域和
【题目】:1314. 矩阵区域和
【算法思路】
该题目中需要计算"矩阵前缀和",需要结合"【模板】二维前缀和"里面关于矩阵前缀和计算和使用。
通过
以下是模板,不用死记硬背,画图可以很快推理出来
计算矩阵前缀和:dp[i][j] = dp[i][j-1] + dp[i-1][j] - dp[i-1][j-1] + mat[i - 1][j - 1];
使用部分矩阵前缀和:answer[i][j] = dp[x2][y2] - dp[x2][y1 -1] - dp[x1 - 1][y2] + dp[x1 - 1][y1 - 1];
【细节问题】
1.【通过k长度计算范围前缀和】
2.【mat矩阵同dp表下标映射关系】
这里主要体现为 mat[i][j]
映射到 mat[i - 1][j - 1]
,由于 dp
表的索引是从 1 开始,因此 x1
、x2
、y1
、y2
都需要加 1 来适配原始矩阵的 0-based 索引。
class Solution {
public:vector<vector<int>> matrixBlockSum(vector<vector<int>>& mat, int k) {int m = mat.size(), n = mat[0].size();//创建dp表vector<vector<int>> dp(m + 1, vector<int>(n + 1));//填充dp表数据for(int i = 1; i <= m; i++)for(int j = 1; j <= n; j++)dp[i][j] = dp[i][j-1] + dp[i-1][j] - dp[i-1][j-1] + mat[i - 1][j - 1];//mat[i - 1][j - 1],映射mat表格下标int x1 = 0, y1 = 0, x2 = 0, y2 = 0;//使用dp表填充新表格进行返回vector<vector<int>> answer(m, vector<int>(n));for(int i = 0; i < m; i++)for(int j = 0; j < n; j++){x1 = max(i - k, 0) + 1;y1 = max(j - k, 0) + 1;x2 = min(i + k, m - 1)+ 1;y2 = min(j + k, n - 1) + 1;answer[i][j] = dp[x2][y2] - dp[x2][y1 -1] - dp[x1 - 1][y2] + dp[x1 - 1][y1 - 1];}return answer;}
};
快和小二一起踏上精彩的算法之旅!关注我,我们将一起破解算法奥秘,探索更多实用且有趣的知识,开启属于你的编程冒险!
相关文章:
【优选算法 | 前缀和】前缀和算法:高效解决区间求和问题的关键
算法相关知识点可以通过点击以下链接进行学习一起加油!双指针滑动窗口二分查找 在本篇文章中,我们将深入解析前缀和算法的原理。从基础概念到实际应用,带你了解如何通过前缀和高效解决数组求和、区间查询等问题。无论你是刚接触算法的新手&am…...
『深夜_MySQL』详解数据库 探索数据库是如何存储的
1. 数据库基础 1.1 什么是数据库 存储数据用文件就可以了,那为什么还要弄个数据库? 一般的文件缺失提供了数据的存储功能,但是文件并没有提供非常好的数据管理能力(用户角度,内容方面) 文件保存数据有以…...
Microsoft Entra ID 免费版管理云资源详解
Microsoft Entra ID(原 Azure AD)免费版为企业提供了基础的身份管理功能,适合小型团队或预算有限的组织。以下从功能解析到实战配置,全面展示如何利用免费版高效管理云资源。 1. 免费版核心功能与限制 1.1 功能概览 功能免费版支持情况基础用户与组管理✔️ 支持创建、删除…...
k8s -hpa
hpa定义弹性自动伸缩 1、横向伸缩,当定义的cpu、mem指标达到hpa值时,会触发pods伸展 2、安装metrics-server 收集pods的cpu。mem信息供hpa参照 安装helm curl -fsSl -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 用helm安装metr…...
Web应用开发指南
一、引言 随着互联网的迅猛发展,Web应用已深度融入日常生活的各个方面。为满足用户对性能、交互与可维护性的日益增长的需求,开发者需要一整套高效、系统化的解决方案。在此背景下,前端框架应运而生。不同于仅提供UI组件的工具库,…...
Vue3 + TypeScript 实现 PC 端鼠标横向拖动滚动
功能说明 拖动功能: 鼠标按下时记录初始位置和滚动位置拖动过程中计算移动距离并更新滚动位置松开鼠标后根据速度实现惯性滚动 滚动控制: 支持鼠标滚轮横向滚动(通过 wheel 事件)自动边界检测防止滚动超出内容…...
MyBatis的SQL映射文件中,`#`和`$`符号的区别
在MyBatis的SQL映射文件中,#和$符号用于处理SQL语句中的参数替换,但它们的工作方式和使用场景有所不同。 #{} 符号 预编译参数:#{} 被用来作为预编译SQL语句的占位符。这意味着MyBatis会将你传入的参数设置为PreparedStatement的参数,从而防止SQL注入攻击,并允许MyBatis对…...
Python----卷积神经网络(池化为什么能增强特征)
一、什么是池化 池化(Pooling)是卷积神经网络(CNN)中的一种关键操作,通常位于卷积层之后,用于对特征图(Feature Map)进行下采样(Downsampling)。其核心目的是…...
React Native 从零开始完整教程(环境配置 → 国内镜像加速 → 运行项目)
React Native 从零开始完整教程(环境配置 → 国内镜像加速 → 运行项目) 本教程将从 环境配置 开始,到 国内镜像加速,最后成功运行 React Native 项目(Android/iOS),适合新手和遇到网络问题的开…...
SNR8016语音模块详解(STM32)
目录 一、介绍 二、传感器原理 1.原理图 2.引脚描述 三、程序设计 main文件 usart.h文件 usart.c文件 四、实验效果 五、资料获取 项目分享 一、介绍 SNR8016语音模块是智纳捷科技生产的一种离线语音识别模块,设计适合用于DIY领域,开放用户设…...
驱动开发系列54 - Linux Graphics QXL显卡驱动代码分析(一)设备初始化
一:概述 QXL 是QEMU支持的一种虚拟显卡,用于虚拟化环境中的图形加速,旨在提高虚拟机的图形显示和远程桌面的用户体验;QEMU 也称 Quick Emulator,快速仿真器,是一个开源通用的仿真和虚拟化工具,可…...
通过IP计算分析归属地
在产品中可能存在不同客户端,请求同一个服务端接口的场景。 例如小程序和App或者浏览器中,如果需要对请求的归属地进行分析,前提是需要先获取请求所在的国家或城市,这种定位通常需要主动授权,而用户一般是不愿意提供的…...
【网络原理】从零开始深入理解HTTP的报文格式(二)
本篇博客给大家带来的是网络HTTP协议的知识点, 续上篇文章,接着介绍HTTP的报文格式. 🐎文章专栏: JavaEE初阶 🚀若有问题 评论区见 ❤ 欢迎大家点赞 评论 收藏 分享 如果你不知道分享给谁,那就分享给薯条. 你们的支持是我不断创作的动力 . 王子,公主请阅…...
【前缀和】二维前缀和(模板题)
DP35 【模板】二维前缀和 DP35 【模板】二维前缀和 给你一个 n 行 m 列的矩阵 A ,下标从 1 开始,接下来有 q 次查询,每次查询输入 4 个参数 x1 , y1 , x2 , y2。 请输出以 (x1, y1) 为左上角,(x2,y2) 为右下角的子矩阵的和。 输入描述: 第一行包含三个整数 …...
【开源工具】Python打造智能IP监控系统:邮件告警+可视化界面+配置持久化
🌐【开源工具】Python打造智能IP监控系统:邮件告警可视化界面配置持久化 🌈 个人主页:创客白泽 - CSDN博客 🔥 系列专栏:🐍《Python开源项目实战》 💡 热爱不止于代码,热…...
kotlin 过滤 filter 函数的作用和使用场景
1. filter 函数的作用 filter 是 Kotlin 集合操作中的一个高阶函数,用于根据指定条件从集合中筛选出符合条件的元素。 作用:遍历集合中的每个元素,并通过给定的 lambda 表达式判断是否保留该元素。返回值:一个新的集合ÿ…...
Java泛型(补档)
核心概念 Java 泛型是 Java SE 1.5 引入的一项重要特性,它的核心思想是 参数化类型(Parameterized Types),即通过将数据类型作为参数传递给类、接口或方法,使代码能够灵活地处理多种类型,同时保证类型安全性…...
C语言发展史:从Unix起源到现代标准演进
C语言发展史:从Unix起源到现代标准演进 C语言的诞生与早期发展 C语言的起源可以追溯到上世纪70年代初期,但其真正的萌芽始于1969年的夏天。在计算机发展史上,这是一个具有划时代意义的时刻。 当时,Ken Thompson和Dennis Ritchi…...
nginx 代理时怎么更改 Remote Address 请求头
今天工作中遇到用 localhost 访问网站能访问后台 api,但是用本机IP地址后就拒绝访问,我怀疑是后台获取 Remote Address 然后设置白名单了只能 localhost 访问。 想用 nginx 更改 Remote Address server {listen 8058;server_name localhost;loca…...
解决STM32待机模式无法下载程序问题的深度探讨
在现代嵌入式系统开发中,STM32系列微控制器因其高性能、低功耗和丰富的外设资源而广受欢迎。然而,开发者在使用STM32时可能会遇到一个问题:当微控制器进入待机模式后,无法通过调试接口(如SWD或JTAG)下载程序…...
进程、线程、进程间通信Unix Domain Sockets (UDS)
进程、线程、UDS 进程和线程进程间通信Unix Domain Sockets (UDS)UDS的核心适用场景和用途配置UDS的几种主要方式socketpair() 基本配置流程socketpair() 进阶——传递文件描述符 补充socketpair() 函数struct msghdr 结构体struct iovecstruct cmsghdrstruct iovec 、struct m…...
大数据平台与数据仓库的核心差异是什么?
随着数据量呈指数级增长,企业面临着如何有效管理、存储和分析这些数据的挑战。 大数据平台和 数据仓库作为两种主流的数据管理工具,常常让企业在选型时感到困惑,它们之间的界限似乎越来越模糊,功能也有所重叠。本文旨在厘清这两种…...
Hadoop虚拟机中配置hosts
( 一)修改虚拟机的主机名 默认情况下,本机的名称叫:localhost。 我们进入linux系统之后,显示出来的就是[rootlocalhost ~]# 。为了方便后面我们更加便捷地访问这台主机,而不是通过ip地址,我们要…...
a-upload组件实现文件的上传——.pdf,.ppt,.pptx,.doc,.docx,.xls,.xlsx,.txt
实现下面的上传/下载/删除功能:要求支持:【.pdf,.ppt,.pptx,.doc,.docx,.xls,.xlsx,.txt】 分析上面的效果图,分为【上传】按钮和【文件列表】功能: 解决步骤1:上传按钮 直接上代码: <a-uploadmultip…...
QCefView应用和网页的交互
一、demo的主要项目文件 结合QCefView自带的demo代码 main.cpp #include #include <QCefContext.h> #include “MainWindow.h” int main(int argc, char* argv[]) { QApplication a(argc, argv); // build QCefConfig QCefConfig config; config.setUserAgent(“QCef…...
C++,设计模式,【建造者模式】
文章目录 通俗易懂的建造者模式:手把手教你造电脑一、现实中的建造者困境二、建造者模式核心思想三、代码实战:组装电脑1. 产品类 - 电脑2. 抽象建造者 - 装机师傅3. 具体建造者 - 电竞主机版4. 具体建造者 - 办公主机版5. 指挥官 - 装机总控6. 客户端使…...
Axure疑难杂症:中继器制作下拉菜单(多级中继器高级交互)
亲爱的小伙伴,在您浏览之前,烦请关注一下,在此深表感谢! Axure产品经理精品视频课已登录CSDN可点击学习https://edu.csdn.net/course/detail/40420 本文视频课程记录于上述地址第五章中继器专题第11节 课程主题:中继器制作下拉菜单 主要内容:创建条件选区、多级中继器…...
科研 | 光子技术为人工智能注入新动力
译《Nature》25.4.9 发表文章《A photonic processing boost for AI》 ▶ 基于人工智能(artificial intelligence, AI)的系统正被越来越广泛地应用于从基因数据解码到自动驾驶的各类任务。但随着AI模型的规模和应用的扩大,性能天花板与能耗壁…...
SQL语句练习 自学SQL网 多表查询
目录 Day 6 用JOINs进行多表联合查询 Day 7 外连接 OUTER JOINs Day 8 外连接 特殊关键字 NULLs Day 6 用JOINs进行多表联合查询 SELECT * FROM Boxoffice INNER JOIN movies ON movies.idboxoffice.Movie_id;SELECT * FROM Boxoffice INNER JOIN moviesON movies.idboxoffi…...
北京亦庄机器人马拉松:人机共跑背后的技术突破与产业启示
2025年4月19日,北京亦庄举办了一场具有里程碑意义的科技赛事——全球首个人形机器人半程马拉松。这场人类与20支机器人战队共同参与的21.0975公里竞速,不仅创造了人形机器人连续运动的最长纪录,更成为中国智能制造领域的综合性技术验证平台。…...
大连理工大学选修课——机器学习笔记(6):决策树
决策树 决策树概述 决策树——非参数机器学习方法 参数方法: 参数估计是定义在整个空间的模型 所有训练数据参与估算 所有的检验输入都用相同的模型和参数 非参数方法: 非参数估计采用局部模型 输入空间被分裂为一系列可以用距离度量的局部空间…...
现代前端工具链深度解析:从包管理到构建工具的完整指南
前言 在当今快速发展的前端生态中,高效的工具链已经成为开发者的必备利器。一个优秀的前端工具链可以显著提升开发效率、优化项目性能并改善团队协作体验。本文将深入探讨现代前端开发中最核心的两大工具类别:包管理工具(npm/yarn)和构建工具(Webpack/V…...
[C语言]猜数字游戏
文章目录 一、游戏思路揭秘二、随机数生成大法1、初探随机数:rand函数的魔力2、随机数种子:时间的魔法3、抓住时间的精髓:time函数 三、完善程序四、游戏成果1、游戏效果2、源代码 一、游戏思路揭秘 猜数字游戏,这个听起来就让人…...
【Linux】g++安装教程
Linux上安装g教程 实现c语言在Linux上编译运行 1. 更新软件包列表 打开终端,先更新软件包列表以确保获取最新版本信息: sudo apt update2. 安装 build-essential 工具包 build-essential 包含 g、gcc、make 和其他编译所需的工具: sudo…...
MQTT - Android MQTT 编码实战(MQTT 客户端创建、MQTT 客户端事件、MQTT 客户端连接配置、MQTT 客户端主题)
Android MQTT 编码实战 1、Settting 在项目级 build.gradle 目录下导入 MQTT 客户端依赖 implementation org.eclipse.paho:org.eclipse.paho.mqttv5.client:1.2.5 implementation org.eclipse.paho:org.eclipse.paho.android.service:1.1.1AndroidManifest.xml,…...
Redis分布式锁使用以及对接支付宝,paypal,strip跨境支付
本章重点在于如何使用redis的分布式锁来锁定库存。减少超卖,同时也对接了支付宝,paypal,strip跨境支付 第一步先建立一个商品表 CREATE TABLE sys_product (id bigint(20) NOT NULL AUTO_INCREMENT COMMENT 主键,code varchar(60) DEFAUL…...
沙箱逃逸(Python沙盒逃逸深度解析)
沙箱逃逸(Python沙盒逃逸深度解析) 一、沙盒逃逸的核心目标 执行系统命令 通过调用os.system、subprocess.Popen等函数执行Shell命令,例如读取文件或反弹Shell。 文件操作 读取敏感文件(如/etc/passwd)、写入后门文件…...
k8s-Pod生命周期
初始化容器 初始化容器是在pod的主容器启动之前要运行的容器,主要是做一些主容器的前置工作,它具有两大特征: 1. 初始化容器必须运行完成直至结束,若某初始化容器运行失败,那么kubernetes需要重启它直到成功完成 2. 初…...
基于Springboot + vue实现的中医院问诊系统
项目描述 本系统包含管理员、医生、用户三个角色。 管理员角色: 用户管理:管理系统中所有用户的信息,包括添加、删除和修改用户。 配置管理:管理系统配置参数,如上传图片的路径等。 权限管理:分配和管理…...
computed计算值为什么还可以依赖另外一个computed计算值?
在 Vue(或类似的响应式框架)中,computed 计算属性之所以可以依赖另一个 computed 属性,是因为: ✅ 本质上 computed 是响应式依赖的“派生值” 每个 computed 本质上就是一个 基于其他响应式数据计算出来的值。 当你在…...
近期实践总结
一、计算机二级考试到底教会了我们什么? 1、概况 根据本人复习、考试的经验,不难发现里面的试题或多或少有些死板(甚至可以说落后于时代),当今时代已经不是二十年前什么都需要手搓的时代了,引擎、集成类软…...
Arduion 第一天,变量的详细解析
Arduino变量详解与嵌入式开发扩展 一、变量基础篇 1.1 变量声明与初始化 <ARDUINO>int ledPin 13; // 声明并初始化float sensorValue; // 先声明后赋值unsigned long startTime; // 无符号长整型void setup() {sensorValue analogRead(A0) *…...
【每日八股】复习 MySQL Day3:锁
文章目录 昨日内容复习MySQL 使用 B 树作为索引的优势是什么?索引有哪几种?什么是最左匹配原则?索引区分度?联合索引如何排序?使用索引有哪些缺陷?什么时候需要建立索引,什么时候不需要…...
2025年KBS新算法 SCI1区TOP:长颖燕麦优化算法AOO,深度解析+性能实测
目录 1.摘要2.算法原理3.结果展示4.参考文献5.文章&代码获取 1.摘要 本文提出了一种新颖的元启发式算法——长颖燕麦优化算法(AOO),该算法灵感来自动画燕麦在环境中的自然行为。AOO模拟了长颖燕麦的三种独特行为:(i) 通过自然…...
1.4 点云数据获取方式——结构光相机
图1-4-1结构光相机 结构光相机作为获取三维点云数据的关键设备,其工作原理基于主动式测量技术。通过投射已知图案,如条纹、点阵、格雷码等,至物体表面,这些图案会因物体表面的高度变化而发生变形。与此同时,利用相机从特定...
2025.4.29总结
工作:最近手头活变得多起来了,毕竟要测两个版本,有时候觉得很奇怪,活少的时候,又想让别人多分点活,活多的时候,又会有些许不自然。这种反差往往伴随着项目的节奏,伴随着两个极端。所…...
初探RAG
源码 核心工作流程 读取文件的内容将内容保存在向量数据库检索向量数据库用户的问题用户问题 上下文【向量数据】 > LLM 读取文件内容【pdf为例】 from pdfminer.high_level import extract_pages from pdfminer.layout import LTTextContainerclass PDFFileLoader():d…...
AIGC(生成式AI)技术全景图:从文本到图像的革命
AIGC(生成式AI)技术全景图:从文本到图像的革命 前言 生成式人工智能(AIGC)正以惊人的速度重塑数字内容的生产方式。从GPT系列模型的文本生成,到Stable Diffusion的图像创作,再到Sora的视频合成…...
通信协议:数字世界的隐形语言——从基础认知到工程实践-优雅草卓伊凡
通信协议:数字世界的隐形语言——从基础认知到工程实践-优雅草卓伊凡 一、理解通信协议:数字世界的”隐形语法” 1.1 通信协议的不可见性与现实存在 通信协议如同空气中的无线电波,虽然看不见摸不着,却实实在在支撑着现代数字世…...
RPC复习
RPC复习 RPC (远程过程调用) 全面解析一、RPC 定义与核心作用1. 什么是RPC?2. 核心作用 二、主流RPC框架对比三、RPC适用场景四、RPC的缺陷五、RPC vs REST vs GraphQL六、Java实现案例:使用Dubbo框架案例描述1. 环境准备2. 定义服务接口3. 服务提供方实…...