【贪心算法】贪心算法一

贪心算法一

  • 1.柠檬水找零
  • 2.将数组和减半的最少操作次数
  • 3.最大数
  • 4.摆动序列

在这里插入图片描述

点赞👍👍收藏🌟🌟关注💖💖
你的支持是对我最大的鼓励,我们一起努力吧!😃😃

1.柠檬水找零

题目链接: 860. 柠檬水找零

题目分析:

在这里插入图片描述

这里有两点需要注意:

  1. 顾客排队购买你的产品
  2. 一开始你手头没有任何零钱,你要拿着顾客的钱去找钱

顾客排队购买你的产品,也就是说如果第一个顾客给你10或者20美元你就找不了,返回false。

算法原理:

这里我们只关注正确的贪心策略,不用管它怎么来的。最后我们来证明一下。

贪心可不是上来就贪,而是在分析问题的过程中,发现可以贪,我们才贪。

这道题就是一个找零问题,顾客会给5美元,10美元,20美元。我们分情况给他找钱就可以了。

在这里插入图片描述
当顾客给5块钱,我们直接收下就行了

在这里插入图片描述
当顾客给10块钱,我们要找5块钱,顺手把10块钱收下,但是找5元前提是我们有5块钱可以找,如果没有返回false

在这里插入图片描述
当顾客给20块钱,关于20块钱找零其实我们有两种策略,
第一种:找一张10块钱,在找一张5块钱
第二种:找三张5块钱

此时就有分歧了,我们要想哪一种最好,这就体现了贪心。贪心就体现在这一步,我们应该选择更优的策略来完成这个找零工作。

到底那个优秀,其实是根据5块钱来的,5块钱不仅完成20块钱找零工作,还能完成10块钱找零工作。因此我们尽量保留5块钱。

所以看起来当前最优策略就是第一种策略。如果第一种策略不成立,我们再选第二种策略,如果第二种策略都不成立就返回false

在这里插入图片描述

class Solution {
public:bool lemonadeChange(vector<int>& bills) {int five = 0, ten = 0;for(auto e : bills){if(e == 5) five++;else if(e == 10){if(five == 0) return false;five--; ten++;}else{if(ten && five) //贪心{ten--; five--;}else if(five >= 3){five -= 3;}else return false;}}return true;}
};

证明:贪心策略是正确的

证明策略:交换论证法

假设
贪心策略解决这道题的方法顺序是:a、b、c、d、e、f,
最优解解决这道题的方法顺序是:e、b、c、d、a、f

此时如果在不破坏最优解的 “最优性质的” 前提下,能够将最优解调整成贪心解。那我们就说贪心解就是最优解。

在这里插入图片描述

这就是我们的交换论证法,交换论证法的核心就是找到不破坏最优性质的前提下把假设出来的最优解逐步的调整出贪心解。

如果顾客给我们5美元或者10美元,贪心解和最优解是没有区别的。5块就收下,10块就找5块。

在这里插入图片描述
唯一的区间就是20美元

贪心解策略是有限选择10+5,但是最优解有可能和贪心解不一样选择的是5+5+5。如果一样肯定不考虑,考虑的肯定是不一样的情况。

假设从左往右扫描第一次碰到20美元下不同的时候,我们看看能不能把最优解调整成贪心解。

在这里插入图片描述
其实就盯着10美元就可以了。因为贪心解这里用到10,最优解这里没有用到10。那么此时10美元就有两种情况了,第一种情况10美元在后面找零过程没有用到,也就是贪心解用来10,但是最优解在后面的找零操作并没有用到10,10块钱装到兜里了。那么此时我们就可以把最优解的两个5替换成兜里的10块钱。这个替换并不影响最优性质,因为这个10在后面找零操作就没有用过。

最优解能解决问题,替换完之后的10也能解决问题

在这里插入图片描述

第二种情况,10美元在后面的换零操作有一次用过了。此时我们依旧可以把前两个5用后面的10交换。前面用10,后面用两个5,交换后依旧不影响最优性质。然后又和贪心解一模一样。

在这里插入图片描述

你会发现最优解用或者不用10,都可以把它替换成和贪心解一样的形式。也就说从前往后扫描只要不相等就调整,那最终一定能把最优解逐步调整成贪心解,并且最优解是可以解决问题,那贪心解也一定能解决问题。所以贪心解就和最优解是等价的。

2.将数组和减半的最少操作次数

题目链接: 2208. 将数组和减半的最少操作次数

题目描述:

在这里插入图片描述

算法原理:

这道题把题意搞清楚之后,想让我们用最少的操作次数把数组和至少减少到之前的一半,那我们肯定会想到每次挑选的时候挑选当前数组里最大的数给它减半,因为挑数组最大的数减半才有可能最快的把整个数组的和减少到之前的一半。

解法:贪心

具体策略:每次挑选当前数组中,最大的那个数,然后减半,直到数组和减少到至少一半为止。

实现我们这个策略的核心就是循环这一步,每次挑选当前数组中,最大的那个数。如果每次都去遍历数组挑最大的那个数,时间复杂度是非常恐怖的,这里我们可以使用优先级队列这个数据结构建立一个大根堆。

解法:贪心 + 大根堆

class Solution {
public:int halveArray(vector<int>& nums) {priority_queue<double> heap;double sum = 0.0;for(auto e : nums) {heap.push(e);sum += e;}sum /= 2.0;int count = 0;while(sum > 0){double t = heap.top() / 2.0;heap.pop();sum -= t;count++;heap.push(t);}return count;}
};

证明

证明策略:交换论证法

这里在说明一点,不管用什么方法证明,一定得要结合题意和贪心策略来证明。

我们这里的题意是每次挑选一个数直到数组和减半,
假设贪心解每次挑选数,这里用横线上面的点表示每次挑选的数。同样最优解也是这样表示。贪心解挑选的数个数大于或者等于最优解的数个数。

在这里插入图片描述
我们只要能想到一个转化规则,在不破坏最优解的 “最优性质的” 前提下,能够将最优解调整成贪心解。就可以了。

那我们从左到右扫描贪心解和最优解。先找到第一次两者不一样的地方。假设贪心解挑的是x,最优解挑的是y,此时我们只要能把y变成x就可以了。

在这里插入图片描述

如何变,紧扣题意和贪心策略,在我们贪心解里面挑的数组中最大的数,最优解如果没有挑最大那个数,那么这里有一个不等式,x > y

在这里插入图片描述

对于x在最优解中它有两种情况,第一种情况,x没有用过。此时可以大胆将y替换成x,因为x > y,你用一个小的数减半就能让整个数组和减半,那选一个更大的数减半那更能让整个数组和减半。即使后面有y/2,y/4等都可以用x替换y。

在这里插入图片描述

第二种情况,x在后续最优解使用了,那我们依旧可以将y与x交换。因为在最优解先用x减半和后用y减半并不影响最优解的最少操作次数。即使在y和x中间可能使用了y/2,y/4,但是把y交换到后面去了,那就没有y/2,y/4这些数,那逻辑不就错了吗。其实可以把y和x交换完之后,把y/2,y/4,y重新排一下序,还是 y,y/2,y/4的使用。

在这里插入图片描述

此时我们在处理最后一个情况,贪心解的次数可能是比最优解次数多的,但是这种情况是绝对不可能的,因为我们从前往后扫描的时候,只要遇到不同都可以用这两种情况进行调整。所以说当最优解解决完情况后,贪心解也一定减半了。所以最优解的操作次数和贪心解的操作次数是一样的。

在这里插入图片描述

到这里就证明完毕了。原因就是从前往后扫描两个解的时候,只要有一个地方不一样,就可以通过这两个策略进行调整,所以最优解就可以在不失去最优性的前提下转化为贪心解。所以当最优解是最少操作次数解决这个问题的时候,贪心解也是最少操作次数解决这个问题的时候。

3.最大数

题目链接: 179. 最大数

题目分析:

在这里插入图片描述

示例1,[10,2] 它所形成的最大整数就是这个数组里面按照从左往右的顺序把数拼起来就可以了。比如这个数组不去休息顺序从左往右拼起来就是102,如果调整一下顺序拼接就是210,201显然大于102,所以示例1所能拼成的最大整数就是210.

但是有可能输出结果可能非常大,所以你需要返回一个字符串而不是整数。

算法原理:

如果把这道题的题意搞清楚之后会发现这道题特别像是一道排序题。无非就是给一个数组按照它给的规则把数组排下序使其形成一个最大的数。

所以先回忆之前正常的排序看能否给我们这道题带来一些启发

正常的排序(升序)
[4,10,8]

不管是之前学习过的冒泡,快排,归并等排序,它们都是干一件事情,就是确定这些元素的先后顺序。只要能搞清楚这些元素谁在前面、谁在中间、谁在后面,我们就能完成这些元素的排序。

所以正常的排序本质:确定元素的先后顺序:谁在前,谁在后。

其中确定元素的先后顺序是根据一定的排序规则来确定

在这里插入图片描述

本题的排序其实也是在确定元素的先后顺序,所以我们仅需找一个排序规则就可以了。

排序规则,其实例一[10,2]已经给我们了,先把这两个数拼接成102和210,然后我们会发现把2放在前面把10放在后面是优于102,因此我们得到一个结果把2放前面,10放后面。

在这里插入图片描述

我们可以把这两个数抽象出来,a表示第一个数,b表示第二个数。
此时我们会得到两种情况,要么a在前b在后,要么b在前a在后

如果发现a在前b在后这种拼接是优于把b在前a在后的拼接,我们可以得到a可以放放在前面,b放在后面。

在这里插入图片描述

如果发现b在前a在后这种拼接和把a在前b在后的拼接是一样的,那就无所谓。

在这里插入图片描述

如果发现b在前a在后这种拼接是优于把a在前b在后的拼接,我们可以得到b可以放放在前面,a放在后面。

在这里插入图片描述

这就是我们这道题里面的排序规则。基于这样的排序规则会发现它们俩是非常一样的,这里我们可以使用sort进行排序,然后把这个比较规则传给sort。

  1. 我们这个专题不是贪心吗,但是这里贪心体现在哪里呢?

其实贪心就体现在了比较规则,确定谁前谁后的策略就是贪心。

  1. 这一个排序规则,为什么能排序呢?

之前排序规则之所以能排序最重要的就是传递性。a > b,b > c ----> a > c,可以推出来 a 在 b 前面,b 在 c 前面,又因为 a > c,所以 a 在 c 前面。所以符合 a b c。

在这里插入图片描述

如果此时a > b,b > c 推不出来 a > c,就不能排序。因为a > b 可以推出 a 在 b 前面,b > c 可以推出 b 在 c 前面,如果推不出来 a > c 的意思是 c 可能大于 a,如果 c > a ,那 a 就在 c 的后面,此时根本就不可能。数组就不能排序。

在这里插入图片描述

上面传递性太明显了,所以极有可能会忽略,但是我们这道题不能忽略这一点。如果知道 ab > ba,bc > cb 推出 a 在 b 的前面,b 在 c 的前面,如果在能知道ac > ca a 在 c 的前面,才能摆出 a b c

但是能不能推出这一点,需要后面去证明。

在这里插入图片描述

这里写代码还有两个细节问题:

第一个细节:把数转化成字符串,然后拼接成字符串,比较字典序。

如果不这样搞还需要算两个数有多少位,然后一个数乘于位数在加上另一个数才能得到一个拼接的数。

第二个细节:这道题有可能传递 [0,0]这样的数组,如果按照之前的策略那就会返回一个 “00” 字符串。但是我们要的是一个数,我们要把字符串搞成 “0” 才行。我们可以判断一下最后的结果ret,如果第一个字符是 “0” 说明后面应该全都是 “0”,那我们最终返回 “0” 这个字符串就可以了。为什么后面应该全都是 “0”,如果后面的是不是0的话,0放在最后一个位置绝对不可能是最大数。

class Solution {
public:string largestNumber(vector<int>& nums) {// 优化: 把所有的数转化成字符串vector<string> strs;for(int x : nums) strs.push_back(to_string(x));// 排序sort(strs.begin(), strs.end(), [](const string& s1, const string& s2){return s1 + s2 > s2 + s1;});// 提取结果 string ret;for(auto& s : strs) ret += s;if(ret[0] == '0') return "0";return ret;}
};

证明:

这里我们只要证明我们这个策略是可以排序的就可以了。

如何证明一个东西可以排序呢?这里要用到数学的知识。

证明方法:数学知识(全序关系)

全序关系的用处:假设有一个集合,集合里有很多元素,全序关系的作用就是从这个集合中任意挑选两个元素,如果这两个元素在定义的比较规则下,如果满足全序关系的话,我们就说这个集合是可以排序的。

全序关系分为三个性质,也就是说只要满足三个性质就有全序关系。

  1. 完全性

从集合中任意挑选两个元素 a、b,它必定会存在两个关系的一个,要么 a <= b,要么 a >= b。如果挑选的两个元素压根没有大小关系,根本不知道谁在前谁在后。所以完全性就是能够排序的最前提条件:任意挑选两个元素能够比大小。

在这里插入图片描述

  1. 反对称性

还是任意挑选两个元素a、b,如果知道 a <= b 且 a >= b,那必须能够推出 a = b,如果得不到这个结果,那么整个数组排序把a放在前面b放在后面是一种排序结果,把b放在前面a放在后面还是一种排序结果。那么整个集合就不能排序,因为整个集合要想排序那最终结果是唯一的才行。

在这里插入图片描述

  1. 传递性

任意挑三个元素a、b、c,如果 a >= b,b >= c,那一定要推出a >= c 。这一点上面已经说过了如果不满足排序不出来最终结果。

在这里插入图片描述

我们要证明的是排序规则,任意挑两个数a、b,然后看 ab 和 ba 这个情况的大小,然后确定a和b的前后顺序。

  1. 证明完全性

挑出a、b,然后看a拼接b,b拼接a是能够比大小的就可以了。

第一种证明:

ab拼接后是一个数,ba拼接后也是一个数。数和数之间是能够比大小的。要么ab >= ba,要么 ba >= ab。

在这里插入图片描述

第二种证明:

设a的位数为 x 位, b的位数为 y 位。
ab拼接的结果是可以表示出来的:10^ya + b
ba:10^x
b + a

既然这两个数能明确表示出来,那一定能比大小。
在这里插入图片描述

  1. 证明反对称性

如果 ab <= ba 且 ab >= ba,那我们要能得到 ab = ba 这个结论。

将ab和ba用刚才的进行处理,因为这里是一个一个的数,设ab为m,ba为n,此时我们能得到一个夹逼定理。m <= n <= m,我们可以得到 m = n。所以我们可以根据1、2得到3。

在这里插入图片描述

  1. 证明传递性

还是任取三个数a、b、c,如果ab >= ba 且 bc >= cb 我们必须要推出来ac >= ca
,ac >= ca的意思是a在前c在后,也就是说a在前,b在后,我们要能推出来a在前,c在后才行。

我们证明方法和上面一样,把不等式写成一个确切的数

在这里插入图片描述

这里特殊情况要考虑一下,如果a、b、c其中任意一个可能等于0, 假如a是0的话,那x位数就是为0。小学我们就知道0不是一个个位数,但是这道题里我们把0这个数当成一个个位数。如a是12,b为0,ab为120

在这里插入图片描述

如果能由1和2这两个式子能推出来第3个式子,那么这个式子就成立

在这里插入图片描述

我们观察一下三个式子发现第三个式子是没有b的,因此我们仅需通过1和2两个式子把b给消掉就可以了。我们可以把b的系数移过去就可以把b消掉,但是移系数要注意系数不能为0,但是刚才处理特殊情况的时候说过x绝对不可能等于0的,那么10^x绝对不可能等于1,所以我们可以大胆移第一个式子b的系数。同样第二个式子也是。

在这里插入图片描述

10^y - 1不可能为0,两步同时消掉,然后在移项就可以得到第三个式子
在这里插入图片描述

到此证毕,我们这个排序规则既有完全性,又有反对称性,又有对称性,因此具有全序关系。有全序关系就说明我们这里定义的排序规则是可以排序的。

4.摆动序列

题目链接:376. 摆动序列

题目分析:

在这里插入图片描述

摆动序列就是一上一下。注意仅有一个元素或者含两个不等元素的序列也视作摆动序列,返回摆动序列 的 最长子序列的长度。
在这里插入图片描述

算法原理:

这里我们就不写具体的数了,而把数当成折线图的形式。目前先不考虑水平这样的形式,先考虑相邻两个元素不同的形式,最后在把水平的处理一下

在这里插入图片描述

如果图是这样的,如何找它的最长摆动序列呢?
我们肯定有这样的想法,把左边和右边的点挑出来,然后在把所有极大值点和极小值点也挑出来,所形成的序列就是一个最长摆动序列。

这个策略确实是可以的,我们的贪心策略最终也和这个策略长的一样。

在这里插入图片描述

接下来我们就来贪一下,我们要找到的是最长摆动序列,相当于就是在这个图中尽可能的挑一些点出来所形成的序列是摆动序列。

既然是尽可能挑多的点,那第一个点就给选上,接下来挑选第二个点的时候继续贪,当前右边这么多点我选择那个点看起来是最优的,此时就有分情况讨论的过程

在这里插入图片描述

第一种情况在上升的线上选一个点,但是在上升的这条线上选都没有第三种情况好,因为选了上升线上一个点接下来要去选下降的,如果挑选这些较小上升的点,那在挑选下降的点可供选择的空间就小了。比如画×的点就选不到了。

在这里插入图片描述
第二种情况选择右边的某个点,如果选了这个点,那摆动系列绝对不可能是最长的,因为中间还有可以选择的一上一下的点。

在这里插入图片描述

同样选了这个点也会错失一个拐点,那摆动序列也不会是最长的。

在这里插入图片描述

可能还会选这条下降线的点,有可能是会最长的,但是并不保险,有可能这条线没有点,所以不如选第三种情况这个点。

在这里插入图片描述

固定两个点之后,考虑第三个点依旧和选择第二个点一样分情况讨论,如果是下降选择不能在下降的点,如果是上升选择不能在上升的点。直到所有点都选完,就是最长摆动子序列。

在这里插入图片描述

你会发现我们贪心挑选出来的点就是把极大值和极小值还有两个端点的值跳出来。

贪心:统计出所有的波峰以及波谷的个数
然后在把左右两个点加上就可以了。

在这里插入图片描述

那如何统计出最终的结果呢?

首先如何确定一个点是波峰还是波谷,

波峰:当前这个点减左边的点如果是正,右边的点减去当前的点如果是负,就是波峰。

波谷:当前这个点减去左边的点如果是负,右边的点减去当前的点如果是正,就是波谷。

也就是说当前这个点左右是相反的就可以确定要么是波峰要么是波谷。

在这里插入图片描述

还有一个问题,如果相邻两个元素是相同的就麻烦了,它会分成两大类,
第一类:相同的时候左右增减趋势是相同的
第二类:相同的时候左右增减趋势是相反的

在这里插入图片描述
第一类是没有波峰波谷的,第二类是有的。虽然是有相同的元素,但是第一类总体要么上升、要么下降,不需要统计波峰波谷。第二类要么下降后上升、要么上升后下降,是需要统计波峰波谷的。

但是相同元素该统计那一个呢?并且虽然属于不同类,但是都是左边是是负数右边是0一个不需要统计一个需要统计,还是很恶心的。

在这里插入图片描述

可以用一个变量left记录当前某个点左边的增减趋势,然后上述情况的时候,把这些相同的情况都可以忽略掉。仅需考虑最左边点的增减趋势和最右边点的增减趋势。

在这里插入图片描述
接下来模拟一下,

left就是标记某个点左边的正负,它有三种情况

left = 0(表示第一个点左边既可以上升也可以是下降的)
left > 0(上升)
left < 0(下降)

然后确定某个点的时候仅需算一个它的右边right就行了,right = nums[i+1] - nums[i]
,当left*right <= 0 就是波峰或者波谷,当right = 0 说明遇到相同的元素然后是可以抛弃的,

在这里插入图片描述

class Solution {
public:int wiggleMaxLength(vector<int>& nums) {int n = nums.size();if(n < 2) return n;int left = 0, right = 0, ret = 0;for(int i = 0; i < n - 1 ; ++i){right = nums[i + 1] - nums[i];if(right == 0) continue;if(left * right <= 0) ++ret;left = right;}return ret + 1;}
};

证明:

这道题证明有三种方法:

  1. 反证法
  2. 分类讨论
  3. 交换论证法

这里我们证明方法是反证法:

假设我们的操作是错的,此时它的反命题就是一个正确的,只要我们证明正确的命题是有矛盾的或者有错误的,那原来的命题就是正确的。

我们的贪心解是选择左右端点和极值,假设最后选择的点为n,这里 n = 6

在这里插入图片描述

假设贪心解是错的,那必须会存在一个最优解,在相同的情况下可以选择更多的点,N > 6。我们只要推出最优解是矛盾的或者错误的,那我们贪心解就对了。

在这里插入图片描述

盯着每一个拐点,先看最左边的拐点,我们这是一个连续的区间,左边元素比它小,右边元素也比它小,在它这个左右区间里一定会出现一个极大值,要么该点是极大值点要么就是区间内的其他点。

在这里插入图片描述

在看下一个拐点,左右两侧都是比它大的,又因为是连续的,所以在这个区间里面必定会存在一个极小值。

同理后面也可以得到极大值,极小值。

在这里插入图片描述

因此可以推出在最优解里,极值点个数是N-2(舍去左右两端点),但是这个N-2是不存在的。因为在贪心解里面我们是可以推出来极值点个数是n-2=4,因为最优解N>6,所以它的极值点个数是N-2 > 4的,但是极值点个数是不可能大于4的,所以最优解压根就是不存在的,因为贪心解得到极值点个数是4,你这个最优解算出考虑极值点个数大于4,这是不符合实际情况的。所以这个最优解是不存在的,因此贪心解是正确的。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Linux】【Vim】Vim 基础

Vim/Gvim 基础 文本编辑基础编辑操作符命令和位移改变文本重复改动Visual 模式移动文本(复制、粘贴)文本对象替换模式 光标移动以 word 为单位移动行首和行尾行内指定单字符移动到匹配的括号光标移动到指定行滚屏简单查找 /string标记 分屏vimdiff 文本编辑 基础编辑 Normal 模…

Gitlab runner的使用示例(二):Maven + Docker 自动化构建与部署

Gitlab runner的使用示例&#xff08;二&#xff09;&#xff1a;Maven Docker 自动化构建与部署 在本篇文章中&#xff0c;我们将详细解析一个典型的 GitLab CI/CD 配置文件&#xff08;gitlab-ci.yml&#xff09;&#xff0c;该文件主要用于通过 Maven 构建 Java 应用&…

07_Python数据类型_集合

Python的基础数据类型 数值类型&#xff1a;整数、浮点数、复数、布尔字符串容器类型&#xff1a;列表、元祖、字典、集合 集合 集合&#xff08;set&#xff09;是Python中一个非常强大的数据类型&#xff0c;它存储的是一组无序且不重复的元素&#xff0c;集合中的元素必须…

Games101学习 - 着色

本文主要讲述Games101中的着色部分。 文中将使用UE的UTexture2D接口&#xff0c;若不了解可以看这篇&#xff1a; https://blog.csdn.net/grayrail/article/details/142165442 1.面积比计算三角形坐标 通过三角形面积比可以得到三角形的坐标alpha、beta、gamma从而进行插值&a…

AI技术好书推荐:《AI系统-原理与架构》

今年1月份在B站发现了一个B站宝藏博主&#xff0c;发布的一系列AI技术类科普视频内容很干&#xff0c;逻辑清晰&#xff0c;很多知识点讲的深入浅出&#xff0c;非常有用&#xff0c;被直接种粉。 后来这一系列的课程内容博主有了出书的计划&#xff0c;机缘巧合有幸参与部分章…

CSS入门笔记

目录 概述 组成 CSS 语法 常见的使用方式 CSS 优先级 CSS 选择器 1. 基本选择器 2. 属性选择器 3. 伪类选择器 4. 组合选择器 示例 优先级 边框样式与盒子模型 单个边框 边框轮廓&#xff08;Outline&#xff09; 盒子模型 模型介绍 边距设置 布局示例 文…

计算机考研408-计算机网络

【题33】下列选项中&#xff0c;不属于网络体系结构所描述的内容是&#xff08;&#xff09; A.网络的层次 B.每一层使用的协议 C.协议的内部实现细节 D.每一层必须完成的功能 解析&#xff1a; 本题考查的是网络体系结构相关的概念。 图1描述了网络的7层架构以及每一层所要完成…

Python模块和包:标准库模块(os, sys, datetime, math等)②

文章目录 一、os 模块1.1 获取当前工作目录1.2 列出目录内容1.3 创建和删除目录1.4 文件和目录操作 二、sys 模块2.1 获取命令行参数2.2 退出程序2.3 获取 Python 版本信息 三、datetime 模块3.1 获取当前日期和时间3.2 日期和时间的格式化3.3 日期和时间的运算 四、math 模块4…

代理IP批理检测工具,支持socks5,socks4,http和https代理批量检测是否可用

代理IP批理检测工具,支持socks5,socks4,http和https代理批量检测是否可用 工具使用c编写&#xff1a; 支持ipv4及ipv6代理服务器。 支持http https socks4及socks5代理的批量检测。 支持所有windows版本运行&#xff01; 导入方式支持手工选择文件及拖放文件。 导入格式支持三…

【我的 PWN 学习手札】劫持 tcache_perthread_struct

目录 前言 一、tcache perthread struct 二、劫持 tcache_perthread_struct 三、测试与模板 前言 tcache 是 glibc 2.26 (ubuntu 17.10) 之后引入的一种技术&#xff0c;目的是提升堆管理的性能&#xff0c;与 fast bin 类似。 tcache 引入了两个新的结构体&#xff0c; tc…

机器学习之非监督学习(四)K-means 聚类算法

机器学习之非监督学习&#xff08;一&#xff09;K-means 聚类算法 0. 文章传送1.非监督学习定义2.非监督学习分类2.1 聚类 Clustering2.2 异常检测 Anomaly Detection 3.K-means聚类算法 K-means clustering案例引入算法步骤算法优化成本函数初始化方法K的选择 代码实现 4.案例…

ElementUI 布局——行与列的灵活运用

ElementUI 布局——行与列的灵活运用 一 . 使用 Layout 组件1.1 注册路由1.2 使用 Layout 组件 二 . 行属性2.1 栅格的间隔2.2 自定义元素标签 三 . 列属性3.1 列的偏移3.2 列的移动 在现代网页设计中&#xff0c;布局是构建用户界面的基石。Element UI 框架通过其强大的 <e…

learn C++ NO.17——继承

什么是继承&#xff1f; 用冒号 : 后跟基类名称来声明一个类是从某个基类继承而来的。继承方式可以是 public、protected 或 private&#xff0c;这决定了基类成员在子类中的访问权限。 下面通过代码简单进行一下演示. 派生类Student即子类&#xff0c;而基类Person是它的父…

Ubuntu22.04安装paddle

查看系统版本信息 使用命令lsb_release -a查看系统版本 rootLAIS01:~# lsb_release -a No LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 22.04.5 LTS Release: 22.04 Codename: jammy查看系统支持的cuda版本&#xff0c;使用命令nvidia-smi&#…

基于paddleocr的批量图片缩放识别

说明 在进行ocr文字识别的时候&#xff0c;有时候我们需要使用批量测试的功能&#xff0c;但是有些图片会识别失败或者个别根本识别不出来&#xff0c;这时候我们可以通过对原图片进行缩放&#xff0c;提高图像的分辨率&#xff0c;然后再次识别&#xff0c;这样可以大大提高图…

Canal+RabbitMQ数据同步环境配置

Canal 是阿里巴巴开发的开源工具&#xff0c;主要用于解析 MySQL 的 binlog 日志&#xff0c;从而实现数据同步。Canal 会模拟 MySQL 从库的协议&#xff0c;订阅主库的 binlog&#xff0c;从而获取数据库的变更信息。 将 Canal 解析到的 MySQL 数据库变更消息通过 RabbitMQ 分…

青柠视频云——视频丢包(卡顿、花屏、绿屏)排查

一、问题说明 近期有客户反馈&#xff0c;接入平台的设备经常出来卡顿、花屏、录屏的情况&#xff0c;出现这样的场景很是尴尬。 客户是私有化部署在公网环境&#xff0c;于是我们联系客户&#xff0c;对问题进行追踪排查。 二、场景复现 我们现场情况确认的过程中&#xff0c;…

蓝桥杯嵌入式客观题合集

十四届模拟赛二客观题 解析&#xff1a;STM32微控制器的I/O端口寄存器必须按32位字被访问 解析&#xff1a;微分电路能将三角波转换为方波&#xff1b;积分电路能将方波转换为三角波 解析&#xff1a;放大电路的本质是能量的控制与转换 解析&#xff1a;具有n个节点&#xff0c…

修改Docker默认存储路径,解决系统盘占用90%+问题(修改docker root dir)

随着Docker技术的广泛应用&#xff0c;它极大地简化了复杂项目的部署与维护流程&#xff0c;仅凭单一镜像即可轻松运行。然而&#xff0c;随着数据量不断增长&#xff0c;Docker的默认数据存储方式可能逐渐成为挑战&#xff0c;尤其是当默认安装于根目录&#xff08;“/”&…

【雪球-注册安全分析报告-无验证方式导致安全隐患】

前言 由于网站注册入口容易被黑客攻击&#xff0c;存在如下安全问题&#xff1a; 1. 暴力破解密码&#xff0c;造成用户信息泄露 2. 短信盗刷的安全问题&#xff0c;影响业务及导致用户投诉 3. 带来经济损失&#xff0c;尤其是后付费客户&#xff0c;风险巨大&#xff0c;造…