当前位置: 首页 > news >正文

【优先算法】专题——前缀和

目录

一、【模版】前缀和

参考代码:

二、【模版】 二维前缀和

参考代码:

三、寻找数组的中心下标

参考代码:

四、除自身以外数组的乘积

参考代码:

五、和为K的子数组

参考代码:

六、和可被K整除的子数组

参考代码:

七、连续数组

参考代码:

八、矩阵区域和

参考代码:

总结


一、【模版】前缀和

【模版】前缀和

题目描述:

数组的元素是从标为1开始的,n是数组的个数,q是查询的次数,查询lr这段区间的和。

解法一:暴力解法,直接查找l到r这段区间之和,但是效率太低,查询q次每次遍历一遍数组时间复杂度O(q*N)n和q的数据范围是1到10^5,暴力解法过不了。

解法二:前缀和,快速求出数组中某一个连续区间的和,时间复杂度O(q)+O(N)

第一步:预处理出来一个前缀和数组,我们要要求1到3的和我们用dp[i-1]+arr[i]就是1到3的和了。

dp[i]表示:表示[1,i]区间内所有元素的和。

dp[i] = dp[i-1] + arr[i]

第二步:使用前缀和数组

如下比如我们要查找l~r这段区间的和那么我们直接去dp数组取出下标为r的这个元素,此元素就是1~r的之和我们减去l-1得到的就是l~r这段区间之和。

这里还有一个问题就是为什么下标要从1开始计数:为了处理边界情况

初始化:添加虚拟结点(辅助结点)

参考代码:

#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); //防止溢出for(int i = 0;i<=n;i++) dp[i] = dp[i-1] + arr[i];//3.使用前缀和数组int l,r;while(q--){cin>>l>>r;cout<<dp[r] -dp[l-1]<<endl;}}

时间复杂度:O(q)+O(n) 


二、【模版】 二维前缀和

题目链接:二维前缀和

题目描述:

题目解析: 

1.从第一行第一列开始到第二列,到二行二列。(如下)

2.从第一行第一列开始到第三列,到三行三列。

3.从第一行第二列开始到4列,到三行四列。

算法原理:

解法一:暴力解法,模拟,让我求哪段区间我就加到哪段区间,如下比如让我们全部求出来那就从头加到尾,时间复杂度高,这道题过不了因为时间复杂度为O(n*m*q)

解法二:前缀和

1.预处理出来一个前缀和矩阵

dp[i][j]表示:从[1,1]位置到[i,j]位置,这段区间里面所有元素和。

如下图我们把它抽象出来,这里我们分为四块面积分别为A、B、C、D,我们要求得dp[i][j]这段区间的和,我们A+B+C+D就等于dp[i][j],我们求B和C这段区间的和是不太好求的,所以我们这样求(A+B) + (A + C) + D - A这里减A是因为多算了一个A所以要减掉,A+B这段区间的值非常好求就是dp[i-1][j]这个位置,A+C就是dp[i][j-1]再加上D这个位置的值就是数组里面的arr[i][j]减去A也就是dp[i-1][j-1],这样就推出了我们预处理的公式。如下图:

2.使用前缀和矩阵

如下假如我们要求D这段区间的和那么我们又被分成了四个部分,竟然要求D这段区间的和我们就A+B+C+D求得结果之后我们先减去上面这部分就是A+B这部分因为A+B这部分可以直接算出了,也就是下图绿色小方块那个位置,在减去A+C这部分但是这样我们发现多减了一个A所以我们要加上一个A,D = A+B+C+D - (A+B)-(A+C)+A(通分之后就等于D),A+B+C+D其实就等于dp[x2][y2]然后减去A+B也就是dp[x1 - 1][y2]再减去A+C也就是dp[x2][y1-1]在加上A也就是dp[x1-1][y1-1],我们直接套用公式就能用O(1)的时间复杂度得出结果。

参考代码:

#include <iostream>
#include <vector>
using namespace std;int main() 
{//1.读入数据int n = 0,m = 0,q = 0;cin>>n>>m>>q;vector<vector<long long>>arr(n+1,vector<long long>(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;}

时间复杂为:O(n*m) + O(q)


三、寻找数组的中心下标

题目链接:寻找数组的中心下标

题目描述:

题目解析: 

如下图两边都等于11那么就返回6的下标,如果全是0那么就返回最左边的下标也就是0因为有多个中心下标,不存在则返回-1

解法一:暴力解法,枚举中心下标左边相加的值是否等于右边相加的值,每次枚举一次中心下标都要左边相加右边相加,枚举下标时间复杂O(N),求和依旧使用O(N)的时间复杂度,最终时间复杂度O(N^2)。

解法二:前缀和

我们利用前缀和的思想来实现,竟然要求某一段区间的和那么前缀和预处理出来的那个数组不就可以,我们还要求后面那一段区间的和我们把前缀和改一下改成后缀和就可以了。

我们用f来表示前缀和数组:f[i]表示:[0,i-1]区间,所有元素的和。

f [i]  = f [i-1] + nums[i-1]

g:后缀和数组:g[i]表示:[i+1,n-1]区间,所有元素的和

g [i] = g [i+1] + nums[i+1]

最后进行判断,枚举所有的中心下标从0~n-1然后判断f[i] == g[i],如果有很多中心下标要返回最左边的,所以我们枚举所有的中心下标i,然后判断f[i] == g[i],因为f[i]表示的就是左边所有元素的和g[i]保存的就是右边所有元素的和,判断是否相等如果相等返回i不相等继续往后面找,找到最后一个位置依旧没找到就返回-1

细节问题:

当我们的f等于0的时候我们代入上面发现会越界访问,0~-1这里没有元素所以f(0)= 0

当g等于n-1的时候我们代入上面也会发生越界访问,n-1的右边是没有任何元素的所以g(0) = 0

填写元素顺序,f表是正着填的从左到右,g表是倒着填的从右到左

参考代码:

class Solution {
public:int pivotIndex(vector<int>& nums) {int n = nums.size();vector<int>f(n),g(n);//1.预处理前缀和数组以及后缀和数组for(int i = 1;i<n;i++)f[i] = f[i-1] + nums[i-1];for(int j = n-2;j>= 0;j--)g[j] = g[j + 1] + nums[j+1];//2.使用for(int i = 0;i<n;i++){if(f[i] == g[i])return i;}return -1;}
};

时间复杂度:O(N)


四、除自身以外数组的乘积

题目链接:除自身以外数组的乘积

题目描述:

举个例子: 

除1以为2*3*4等于24,除2以外1*3*4等于12,除3以为1*2*4等于8,除4以为1*2*3等于6,题目已经提示我们了使用前缀和 后缀和。

解法一:暴力解法

暴力解法其实和我们上面举的例子一样,比如我们要求除第一个位置以外的值我们就从头遍历尾,要求第二个位置就从第一个开始遍历跳过我们自己然后依次遍历,以此类推。

但是时间复杂度太高了,O(N^2)

解法二:前缀积

本题的思路和上题的思路一样,但是有些细节有变化。

1.预处理前缀积以及后缀积

我们不需要i位置的元素,只要0~i-1位置的元素即可。表示如下:

f:表示前缀积:f [0,i -1 ] 区间内所有元素的乘积

我们要求i-1位置的乘积的时候我们知道i-2位置的乘积让它乘以i-1位置的值就可以了

f[i] = f [i-1] * nums[i-1]

注意:我们上面的f [i-1 ]位置是上图i-2的位置,因为我们f[i]表示的是i-1位置。

我们知道了i+2位置的乘积之后用它乘以i+1位置的值即可。

g:表示后缀积:g[i]表示:[i+1,n-1]

g[i] = g[i+1] * nums[i+1]

2.使用

我们在i这个位置填写数据的时候我们用f[i] * g[i]因为f[i]表示左边的乘积g表示右边的乘积

3.细节问题

当我们i等于0的时候,其实会越界访问所以我们需要处理,那么我们f(0)给什么值合适上面那道题我们给的是0,这道题我们不能给0因为0*nums[i-1]还是0,那么会影响我们的结果所以我们要给1,f(0) = 1,g(n-1) = 1

参考代码:

class Solution {
public:vector<int> productExceptSelf(vector<int>& nums) {int n = nums.size();vector<int>f(n,1),g(n,1);vector<int> answer(n);//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];//2.使用for(int i = 0;i<n;i++){answer[i] = f[i] * g[i];}return answer;}
};

时间复杂度:O(N)


五、和为K的子数组

题目链接:560. 和为 K 的子数组 - 力扣(LeetCode)

题目描述:

前缀和+哈希表

以i位置为结尾的所有的子数组在[0,i-1]区间内,有多少个前缀和等于sum[i] - k就有多少个和为k的子数组,哈希表中分别存储前缀和、次数。

细节问题:

1.在计算i位置之前,哈希表里面只保存[0,i-1]位置的前缀和

2.不用真的创建一个前缀和数组,用一个变量sum来标记前一个位置的前缀和即可

3.如果整个前缀和等于k那么我们需要提前把hash[0] = 1。<0,1>

注意:不能使用滑动窗口来做优化(双指针)因为有0和负数,如下图这种情况我们left不断向右移动,那么有可能中间还有子数组和为 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;}
};

时间复杂度为 O(n),空间复杂度也为 O(n) 


六、和可被K整除的子数组

题目链接:和可被K整除的子数组

题目描述:

补充知识:

1.同余定理:

(a - b) / p = k.....0    => a % p = b % p

举个例子:(26-12) / 7   =>   26 % 7 = 12 % 7

7 % 2 = 1   -> 7 - 2 = 5 - 2 =3 -2 = 1

取余数的本质就是你这个数有多少个2的倍数就把2的倍数干掉,减到这个数比2小

(1+2 * 3) % 2 = 1(相当于有3个2的倍数,得出等式:(a + p * k) % p = a % p

证明:

(a- b) / p = k

a - b = p * k

a = b + p * k(左右相等,那么左右%p也相等)

a %p = (b + p * k) % p = b % p(p * k有k个p可以直接干掉)

2.C++,java:[负数 % 正数]的结果以及修正

负 % 正 = 负 修正 a % p + p 正负统一(a %p +p) % p(如果a为正数那么就多加了一个p所以再模一个p结果是不变的,如果是负数加上一个p刚好就是正确答案)

我们使用前缀和 + 哈希表

在[0,i-1]区间内,找到有多少个前缀和的余数等于(sun % k + k) % k,哈希表分别存储前缀和的余数、次数

大部分逻辑和上题差不多 

参考代码:

class Solution {
public:int subarraysDivByK(vector<int>& nums, int k) {unordered_map<int,int>hash;hash[0] = 1;//0这个数的余数int sum = 0,ret = 0;for(auto x : nums){sum += x;//算出当前位置的前缀和int r = (sum % k + k) % k;//修正后的余数if(hash.count(r)) ret +=hash[r%k];//统计结果hash[r]++;}return ret;}
};

时间复杂度为 O(n),空间复杂度也为 O(n) 


七、连续数组

题目链接:连续数组

题目描述:

我们把问题转化一下:

1.将所有的0修改为-1

2.在数组中,找出最长的子数组,使子数组中所有的元素和为0

和为k的子数组 ->和为0的子数组

前缀和 + 哈希表

1.哈希表中分别存储前缀和、下标

2.使用完之后,丢进哈希表

3.如果有重复的<sum,i>只保留前面的那一对<sum,i>

4.默认的前缀和为0的情况hash[0] = -1,当我们的这段区间和为sum的时候我们要去0的前面也就是-1的位置找和为0的子区间(存的下标)

5.长度计算i - j + 1 - 1    =>  i - j

参考代码:

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;}
};

八、矩阵区域和

题目链接:矩阵区域和

题目描述:

题目要求:以5为中心分别像上左下右分别扩展k个单位,围城一个长方形的所有元素的和,这是假设k = 1,那么扩展一个单位。

假设求1这个位置,上左下右分别扩展1个单位,然后围成一个正方形,最后相加即可。1+2+4+5

求2这个位置,上左下右分别扩展1个单位然后围成正方形,相加即可,超出矩阵的范围不需要。1+2+3+4+5+6

求5这个位置,上左下右分别扩展1个单位然后围成正方形,相加即可。1+2+3+4+5+6+7+8+9

解法:使用二维前缀和

dp[i][j] = dp[i-1][j]  + dp[i][j-1] -  dp[i-1][j-1] + mat[i][j]

因为多加了一个dp[i-1][j-1]所以再减去一个dp[i-1][j-1]。

如上就是初始化前缀和矩阵的递推公式,直接代入公式即可。

answer= dp[x2][y2] - dp[x1-1][y2] - dp[x2][y1-1] + dp[x1-1][y1-1]

这里加dp[x1-1][y1-1]是因为多减了一个dp[x1-1][y1-1]所以要加上

1.我们要求ans[i][j]位置

我们(i-k,j-k)用(x1,y2)表示

因为这个区间可能会越界,也就是说是(0,0)这个位置的时候我们不能越过,所以我们求一个最大值,如果小于0那么取最大值还是0如果大于0那么就是一个合法的区间。

x1 = max(0,i-k)

y1 = max(0,j-k)

我们(i+k,j+k)用(x2,y2)表示

我们的i+k,j+k可能会超过我们的(m-1,n-1)所以我们需要让它回到我们的m-1,n-1

x2 = min(m-1,i+k)

y2 = min(n-1,j+k) 

2.映射位置 

当我们dp数组要填1,1这个位置的值我们要去mat数组0,0这个位置找。dp(x,y)  -> mat(x-1,y-1)。

所以我们需要把dp[i][j] = dp[i-1][j]  + dp[i][j-1] -  dp[i-1][j-1] + mat[i][j]改为dp[i][j] = dp[i-1][j]  + dp[i][j-1] -  dp[i-1][j-1] + mat[i-1][j-1]

我们在填ans数据的时候使用dp数组需要+1因为ans(0,0)对应dp(1,1)位置。(x,y)  -> (x+1,y+1)。

这里有两种方式:

方法一:

answer[i][j] = dp[x2+1][y2+1] - dp[x1-1+1][y2+1]-dp[x2+1][y1-1+1] +dp [x1-1+1][y1-1+1];

方法二:我们在求下标那里进行+1即可,然后直接在dp数组拿值即可

x1 = max(0,i-k)+1

y1 = max(0,j-k)+1

x2 = min(m-1,i+k)+1

y2 = min(n-1,j+k) +1

参考代码:

class Solution {
public:vector<vector<int>> matrixBlockSum(vector<vector<int>>& mat, int k) {int m = mat.size(),n = mat[0].size();//1.预处理前缀和矩阵vector<vector<int>> dp(m+1,vector<int>(n+1));for(int i = 1;i <= m;i++)for(int j = 1;j<=n;j++)dp[i][j] = dp[i-1][j] + dp[i][j-1] - dp[i-1][j-1] + mat[i-1][j-1];//2.使用vector<vector<int>> answer(m,vector<int>(n));for(int i = 0;i < m;i++){for(int j = 0;j<n;j++){int x1 = max(0,i-k) + 1,y1 = max(0,j-k)+1;int x2 = min(m-1,i+k) + 1,y2 = min(n-1,j+k)+1;answer[i][j] = dp[x2][y2] - dp[x1-1][y2]-dp[x2][y1-1] +dp [x1-1][y1-1];}}return answer;}
};

总结

前缀和这个算法,重要思想就是预处理,当我们在解决一个问题的时候不太好解决的时候我们可以先预处理一下,预处理之后在解决效率是非常高的,直接解决时间复杂度是N^2级别,预处理一下直接变O(N),这种就是典型的用空间换时间,因为我们多创建了一个数组,但是时间复杂度提高了一个级别。

相关文章:

【优先算法】专题——前缀和

目录 一、【模版】前缀和 参考代码&#xff1a; 二、【模版】 二维前缀和 参考代码&#xff1a; 三、寻找数组的中心下标 参考代码&#xff1a; 四、除自身以外数组的乘积 参考代码&#xff1a; 五、和为K的子数组 参考代码&#xff1a; 六、和可被K整除的子数组 参…...

gitea - fatal: Authentication failed

文章目录 gitea - fatal: Authentication failed概述run_gitea_on_my_pkm.bat 笔记删除windows凭证管理器中对应的url认证凭证启动gitea服务端的命令行正常用 TortoiseGit 提交代码备注END gitea - fatal: Authentication failed 概述 本地的git归档服务端使用gitea. 原来的用…...

基于Spring Security 6的OAuth2 系列之八 - 授权服务器--Spring Authrization Server的基本原理

之所以想写这一系列&#xff0c;是因为之前工作过程中使用Spring Security OAuth2搭建了网关和授权服务器&#xff0c;但当时基于spring-boot 2.3.x&#xff0c;其默认的Spring Security是5.3.x。之后新项目升级到了spring-boot 3.3.0&#xff0c;结果一看Spring Security也升级…...

蓝桥与力扣刷题(234 回文链表)

题目&#xff1a;给你一个单链表的头节点 head &#xff0c;请你判断该链表是否为回文链表。如果是&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 示例 1&#xff1a; 输入&#xff1a;head [1,2,2,1] 输出&#xff1a;true示例 2&#xff1a; 输入&…...

Google C++ Style / 谷歌C++开源风格

文章目录 前言1. 头文件1.1 自给自足的头文件1.2 #define 防护符1.3 导入你的依赖1.4 前向声明1.5 内联函数1.6 #include 的路径及顺序 2. 作用域2.1 命名空间2.2 内部链接2.3 非成员函数、静态成员函数和全局函数2.4 局部变量2.5 静态和全局变量2.6 thread_local 变量 3. 类3.…...

Windows图形界面(GUI)-QT-C/C++ - QT Tab Widget

公开视频 -> 链接点击跳转公开课程博客首页 -> ​​​链接点击跳转博客主页 目录 一、概述 1.1 什么是 QTabWidget&#xff1f; 1.2 使用场景 二、常见样式 2.1 选项卡式界面 2.2 动态添加和删除选项卡 2.3 自定义选项卡标题和图标 三、属性设置 3.1 添加页面&…...

【大数据技术】教程05:本机DataGrip远程连接虚拟机MySQL/Hive

本机DataGrip远程连接虚拟机MySQL/Hive datagrip-2024.3.4VMware Workstation Pro 16CentOS-Stream-10-latest-x86_64-dvd1.iso写在前面 本文主要介绍如何使用本机的DataGrip连接虚拟机的MySQL数据库和Hive数据库,提高编程效率。 安装DataGrip 请按照以下步骤安装DataGrip软…...

C++:结构体和类

在之前的博客中已经讲过了C语言中的结构体概念了&#xff0c;重复的内容在这儿就不赘述了。C中的结构体在C语言的基础上还有些补充&#xff0c;在这里说明一下&#xff0c;顺便简单地讲一下类的概念。 一、成员函数 结构体类型声明的关键字是 struct &#xff0c;在C中结构体…...

MATLAB的数据类型和各类数据类型转化示例

一、MATLAB的数据类型 在MATLAB中 &#xff0c;数据类型是非常重要的概念&#xff0c;因为它们决定了如何存储和操作数据。MATLAB支持数值型、字符型、字符串型、逻辑型、结构体、单元数组、数组和矩阵等多种数据类型。MATLAB 是一种动态类型语言&#xff0c;这意味着变量的数…...

UE求职Demo开发日志#19 给物品找图标,实现装备增加属性,背包栏UI显示装备

1 将用到的图标找好&#xff0c;放一起 DataTable里对应好图标 测试一下能正确获取&#xff1a; 2 装备增强属性思路 给FMyItemInfo添加一个枚举变量记录类型&#xff08;物品&#xff0c;道具&#xff0c;装备&#xff0c;饰品&#xff0c;武器&#xff09;--> 扩展DataT…...

C++泛型编程指南09 类模板实现和使用友元

文章目录 第2章 类模板 Stack 的实现2.1 类模板 Stack 的实现 (Implementation of Class Template Stack)2.1.1 声明类模板 (Declaration of Class Templates)2.1.2 成员函数实现 (Implementation of Member Functions) 2.2 使用类模板 Stack脚注改进后的叙述总结脚注2.3 类模板…...

使用MATLAB进行雷达数据采集可视化

本文使用轮趣科技N10雷达&#xff0c;需要源码可在后台私信或者资源自取 1. 项目概述 本项目旨在通过 MATLAB 读取 N10 激光雷达 的数据&#xff0c;并进行 实时 3D 点云可视化。数据通过 串口 传输&#xff0c;并经过解析后转换为 三维坐标点&#xff0c;最终使用 pcplayer 进…...

【Elasticsearch】allow_no_indices

- **allow_no_indices 参数的作用**&#xff1a; 该参数用于控制当请求的目标索引&#xff08;通过通配符、别名或 _all 指定&#xff09;不存在或已关闭时&#xff0c;Elasticsearch 的行为。 - **默认行为**&#xff1a; 如果未显式设置该参数&#xff0c;默认值为 …...

54【ip+端口+根目录通信】

上节课讲到&#xff0c;根目录起到定位作用&#xff0c;比如我们搭建一个php网站后&#xff0c;注册系统是由根目录的register.php文件执行&#xff0c;那么我们给这个根目录绑定域名https://127.0.0.1&#xff0c;当我们浏览器访问https://127.0.0.1/register.php时&#xff0…...

python算法和数据结构刷题[3]:哈希表、滑动窗口、双指针、回溯算法、贪心算法

回溯算法 「所有可能的结果」&#xff0c;而不是「结果的个数」&#xff0c;一般情况下&#xff0c;我们就知道需要暴力搜索所有的可行解了&#xff0c;可以用「回溯法」。 回溯算法关键在于:不合适就退回上一步。在回溯算法中&#xff0c;递归用于深入到所有可能的分支&…...

DeepSeek横空出世,AI格局或将改写?

引言 这几天&#xff0c;国产AI大模型DeepSeek R1&#xff0c;一飞冲天&#xff0c;在全球AI圈持续引爆热度&#xff0c;DeepSeek R1 已经是世界上最先进的 AI 模型之一&#xff0c;可与 OpenAI 的新 o1 和 Meta 的 Llama AI 模型相媲美。 DeepSeek-V3模型发布后&#xff0c;在…...

聚簇索引、哈希索引、覆盖索引、索引分类、最左前缀原则、判断索引使用情况、索引失效条件、优化查询性能

聚簇索引 聚簇索引像一本按目录排版的书&#xff0c;用空间换时间&#xff0c;适合读多写少的场景。设计数据库时&#xff0c;主键的选择&#xff08;如自增ID vs 随机UUID&#xff09;会直接影响聚簇索引的性能。 什么是聚簇索引&#xff1f; 数据即索引&#xff1a;聚簇索引…...

OpenAI 实战进阶教程 - 第四节: 结合 Web 服务:构建 Flask API 网关

目标 学习将 OpenAI 接入 Web 应用&#xff0c;构建交互式 API 网关理解 Flask 框架的基本用法实现 GPT 模型的 API 集成并返回结果 内容与实操 一、环境准备 安装必要依赖&#xff1a; 打开终端或命令行&#xff0c;执行以下命令安装 Flask 和 OpenAI SDK&#xff1a; pip i…...

python的pre-commit库的使用

在软件开发过程中&#xff0c;保持代码的一致性和高质量是非常重要的。pre-commit 是一个强大的工具&#xff0c;它可以帮助我们在提交代码到版本控制系统&#xff08;如 Git&#xff09;之前自动运行一系列的代码检查和格式化操作。通过这种方式&#xff0c;我们可以确保每次提…...

架构技能(四):需求分析

需求分析&#xff0c;即分析需求&#xff0c;分析软件用户需要解决的问题。 需求分析的下一环节是软件的整体架构设计&#xff0c;需求是输入&#xff0c;架构是输出&#xff0c;需求决定了架构。 决定架构的是软件的所有需求吗&#xff1f;肯定不是&#xff0c;真正决定架构…...

RestClient

什么是RestClient RestClient 是 Elasticsearch 官方提供的 Java 低级 REST 客户端&#xff0c;它允许HTTP与Elasticsearch 集群通信&#xff0c;而无需处理 JSON 序列化/反序列化等底层细节。它是 Elasticsearch Java API 客户端的基础。 RestClient 主要特点 轻量级&#xff…...

python打卡day49

知识点回顾&#xff1a; 通道注意力模块复习空间注意力模块CBAM的定义 作业&#xff1a;尝试对今天的模型检查参数数目&#xff0c;并用tensorboard查看训练过程 import torch import torch.nn as nn# 定义通道注意力 class ChannelAttention(nn.Module):def __init__(self,…...

Vue3 + Element Plus + TypeScript中el-transfer穿梭框组件使用详解及示例

使用详解 Element Plus 的 el-transfer 组件是一个强大的穿梭框组件&#xff0c;常用于在两个集合之间进行数据转移&#xff0c;如权限分配、数据选择等场景。下面我将详细介绍其用法并提供一个完整示例。 核心特性与用法 基本属性 v-model&#xff1a;绑定右侧列表的值&…...

深入浅出:JavaScript 中的 `window.crypto.getRandomValues()` 方法

深入浅出&#xff1a;JavaScript 中的 window.crypto.getRandomValues() 方法 在现代 Web 开发中&#xff0c;随机数的生成看似简单&#xff0c;却隐藏着许多玄机。无论是生成密码、加密密钥&#xff0c;还是创建安全令牌&#xff0c;随机数的质量直接关系到系统的安全性。Jav…...

Frozen-Flask :将 Flask 应用“冻结”为静态文件

Frozen-Flask 是一个用于将 Flask 应用“冻结”为静态文件的 Python 扩展。它的核心用途是&#xff1a;将一个 Flask Web 应用生成成纯静态 HTML 文件&#xff0c;从而可以部署到静态网站托管服务上&#xff0c;如 GitHub Pages、Netlify 或任何支持静态文件的网站服务器。 &am…...

P3 QT项目----记事本(3.8)

3.8 记事本项目总结 项目源码 1.main.cpp #include "widget.h" #include <QApplication> int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();return a.exec(); } 2.widget.cpp #include "widget.h" #include &q…...

CSS设置元素的宽度根据其内容自动调整

width: fit-content 是 CSS 中的一个属性值&#xff0c;用于设置元素的宽度根据其内容自动调整&#xff0c;确保宽度刚好容纳内容而不会超出。 效果对比 默认情况&#xff08;width: auto&#xff09;&#xff1a; 块级元素&#xff08;如 <div>&#xff09;会占满父容器…...

让回归模型不再被异常值“带跑偏“,MSE和Cauchy损失函数在噪声数据环境下的实战对比

在机器学习的回归分析中&#xff0c;损失函数的选择对模型性能具有决定性影响。均方误差&#xff08;MSE&#xff09;作为经典的损失函数&#xff0c;在处理干净数据时表现优异&#xff0c;但在面对包含异常值的噪声数据时&#xff0c;其对大误差的二次惩罚机制往往导致模型参数…...

网站指纹识别

网站指纹识别 网站的最基本组成&#xff1a;服务器&#xff08;操作系统&#xff09;、中间件&#xff08;web容器&#xff09;、脚本语言、数据厍 为什么要了解这些&#xff1f;举个例子&#xff1a;发现了一个文件读取漏洞&#xff0c;我们需要读/etc/passwd&#xff0c;如…...

vulnyx Blogger writeup

信息收集 arp-scan nmap 获取userFlag 上web看看 一个默认的页面&#xff0c;gobuster扫一下目录 可以看到扫出的目录中得到了一个有价值的目录/wordpress&#xff0c;说明目标所使用的cms是wordpress&#xff0c;访问http://192.168.43.213/wordpress/然后查看源码能看到 这…...