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

【蓝桥杯软件赛 零基础备赛20周】第6周——栈

文章目录

  • 1. 基本数据结构概述
    • 1.1 数据结构和算法的关系
    • 1.2 线性数据结构概述
    • 1.3 二叉树简介
  • 2. 栈
    • 2.1 手写栈
    • 2.2 C++STL栈
    • 2.3 Java 栈
    • 2.4 Python栈
  • 3 习题

1. 基本数据结构概述

很多计算机教材提到:程序 = 数据结构 + 算法。

“以数据结构为弓,以算法为箭”

数据结构是是计算机存储、组织数据的方法。常用的数据结构有:数组(Array)、栈(Stack)、队列(Queue)、链表(Linked List)、树(Tree)、图(Graph)、堆(Heap)、散列表(Hash)等。分为两大类:线性表、非线性表。数组、栈、队列、链表是线性表,其他是非线性表。

1.1 数据结构和算法的关系

数据结构和算法往往密不可分。下面以图的存储为例,说明数据结构和算法的关系。这几种存图的数据结构,各有优缺点,也各有自己的应用场景。

(1)边集数组

定义结构体数组:

struct Edge{int u, v, w;
}edges[M];

其中(u,v,w)表示一条边,起点是u,终点是v,边长是w。edges[M]可以存M条边。

边集数组的优点:是最节省空间的存图方法,存储空间不可能再少了。n=1000个点,m=5000条边的图,使用的存储空间是12×5000 = 60KB。

边集数组的缺点:不能快速定位某条边。如果要找某点u和哪些点有边连接,得把整个edges[M]从头到尾搜一遍才能知道。

边集数组的的应用场景:如果算法不需要查找特定的边,就用边集数组。例如最小生成树Kruskal算法、最短路径Bellman-ford算法。

(2)邻接矩阵

定义一个二维数组:

	int edge[N][N];

其中edge[i][j]表示点i和点j之间有一条边,边长为edge[i][j]。它可以存N个点的边。若edge[i][j]=0,表示i和j之间没有边;若edge[i][j] != 0,i和j之间有边,边长为edge[i][j]。

邻接矩阵的优点:能极快地查询任意两点之间是否有边。如果edge[i][j] != 0,说明点i和j之间有一条边,边长edge[i][j]。

邻接矩阵的缺点:如果图是一张稀疏图,大部分点和边之间没有边,那么邻接矩阵很浪费空间,因为大多数edge[][]=0,没有用到。n=1000个点,m=5000条边的图,使用的存储空间是12×1000×1000 = 12MB。

邻接矩阵的应用场景:(1)稠密图,几乎所有的点之间都有边,edge[][]数组几乎用满了,很少浪费;(2)算法需要快速查找边,而且计算结果和任意两点的关系有关,例如最短路径算法的Floyd算法。

(3)邻接表

邻接矩阵的优点:十分节省空间,因为只存储存在的边。

邻接矩阵的缺点:没有明显的缺点。它的存储空间只比边集数组大一点点,而查询边的速度只比邻接矩阵慢一点点。

邻接矩阵应用场景:基于稀疏图的大部分算法。

1.2 线性数据结构概述

在所有数据结构中,线性表是最简单的。线性表有数组、链表、队列、栈,它们有一个共同的特征:把同类型的数据一个接一个地串在一起。

下面对线性表做个概述,并比较它们的优缺点。

(1)数组

数组是最最简单的数据结构,它的逻辑结构和物理内存的存储完全一样。例如C语言中定义一个整型数组int a[10],系统会分配一个40字节的存储空间,这100个字符的存储地址是连续的。

#include <bits/stdc++.h>
using namespace std;
int main(){int a[10];for (int i=0;i<10;i++)  cout << &a[i] << " ";  //打印10个整数的存储地址return 0;
}

在作者机器上运行,输出10个整数的存储地址:
0x6dfec4 0x6dfec8 0x6dfecc 0x6dfed0 0x6dfed4 0x6dfed8 0x6dfedc 0x6dfee0 0x6dfee4 0x6dfee8

数组的优点:(1)简单,容易编程;(2)访问快捷,要定位到某个数据,只需使用下标即可,例如a[0]是第1个数据,a[i]是第i-1个数据;(3)与某些应用场景直接对应,例如数列是一维数组,可以在一维护数组上排序,矩阵是二维数组,表示空间坐标,等等。

数组的缺点:删除和增加数据很麻烦,非常耗时。例如要删除数组int a[10]的第5个数据,只能采用覆盖的方法,从第6个数据开始,每个往前挪一位。增加数据也麻烦,例如要在第5个位置插入一个数据,只能把原来第5个开始的数据逐个往后挪一位,空出第5个位置给新数据。

(2)链表

链表是为了克服数组的缺点提出的一种线性表,链表的插入和删除操作,不需要挪动其他数据。简单地说,链表是“是用指针串起来的数组”。链表的数据不是连续存放的,而是用指针串起来的。例如下图删除链表的第3个数据,只要把原来连接第3个数据的指针断开,然后连接它前后的数据即可,不用挪动其他的数据。

在这里插入图片描述

链表的优点:增加和删除数据很便捷。这个优点弥补了数组的缺点。

链表的缺点:定位某个数据比较麻烦。例如要输出第5个数据,需要从链表头开始,沿着指针一步步走,找到第5个。链表的这个缺点却是数组的优点。

链表和数组的优缺点正好相反,它们的应用场合不同,数组适合静态数据,链表适合动态数据。

链表如何编程实现?在常见的数据结构教材中,链表的数据节点是动态分配的,各节点之间用指针来连接。但是在算法竞赛中,如果手写链表,一般不用动态分配,而是用静态数组来模拟。

手写链表的代码见题目:排队顺序

题解

#include<bits/stdc++.h> using namespace std;int arr[1000010];
int main()
{int n;cin >> n;for (int i = 1; i <= n; i++) {cin >> arr[i];}int head;cin >> head;cout << head;while (arr[head] != 0) {cout << " " << arr[head];head = arr[head];}return 0;
}

当然,除非必要,一般不手写链表,而是用系统提供的链表,例如C++ STL的list,Java LinkedList,Python的list。

链表在蓝桥杯等算法竞赛中不太常用,所以本章没有详细介绍。

(3)队列

队列是线性数据的一种使用方式,模拟现实世界的排队操作。例如排队购物,只能从队头离开队伍,新来的人只能排到队尾,不能插队。队列有一个出口和一个入口,出口是队头,入口是队尾。队列的编程实现,可以用数组,也可以用链表。

队列这种数据结构无所谓优缺点,只有适合不适合。例如宽度优先搜索BFS,就是基于队列的,用其他数据结构都不合适。

(4)栈

栈也是线性数据的一种使用方式,模拟现实世界的单出入口。例如一管泡腾片,先放进去的泡腾片后出来。栈的编程比队列更简单,同样可以用数组或链表实现。

栈有它的使用场合,例如递归使用栈来处理函数的自我调用过程。

1.3 二叉树简介

二叉树是一种高度组织性、高效率的数据结构。例如在一棵有n个节点的满二叉树上定位某个数据,只需走logn步,插入和删除某个数据也只需logn步。在二叉树的基础上发展出了很多高级数据结构和算法。大多数高级数据结构,例如树状数组、线段树、树链剖分、平衡树、动态树等,都是基于二叉树的。

2. 栈

栈(stack)是比队列更简单的数据结构,它的特点是“先进后出”。

队列有两个口,一个入口和一个出口。而栈只有唯一的一个口,既从这个口进入,又从这个口出来。所以如果自己写栈的代码,比队列的代码更简单。

2.1 手写栈

如果使用环境简单,最简单的手写栈代码用数组实现。

const int N = 300008;                        //定义栈的大小
struct mystack{int a[N];                                //存放栈元素,从a[0]开始int t = -1;                              //栈顶位置,初始栈为空,置初值为-1void push(int data){ a[++t] = data; }    //把元素data送入栈int top()   { return a[t]; }             //读栈顶元素,不弹出void pop()  { if(t>-1) t--;}             //弹出栈顶int size()  { return t+1;}               //栈内元素的数量int empty() { return t==-1 ? 1:0; }      //若栈为空返回1
};

使用栈时要注意不能超过栈的空间。上面第1行定义了栈的大小是N,栈内的元素数量不要超过它。

用下面的例子给出上述手写代码的应用。

例题:表达式括号匹配

题解:

合法的括号串例如“(())”、“()()()”,像“)(()”这样是非法的。合法括号组合的特点是:左括号先出现,右括号后出现;左括号和右括号一样多。

括号组合的合法检查是栈的经典应用。用一个栈存储所有的左括号。遍历字符串的每一个字符,处理流程是:
(1)若字符是 ‘(’,进栈。
(2)若字符是’)',有两种情况:如果栈不空,说明有一个匹配的左括号,弹出这个左括号,然后继续读下一个字符;如果栈空了,说明没有与右括号匹配的左括号,字符串非法,输出NO,程序退出。
(3)读完所有字符后,如果栈为空,说明每个左括号有匹配的右括号,输出YES,否则输出NO。

C++代码

手写栈:

#include <bits/stdc++.h>
using namespace std;
const int N = 300008;                        //定义栈的大小
struct mystack{int a[N];                                //存放栈元素,从a[0]开始int t = -1;                              //栈顶位置,初始栈为空,置初值为-1void push(int data){ a[++t] = data; }    //把元素data送入栈int top()   { return a[t]; }         //读栈顶元素,不弹出void pop()  { if(t>-1) t--;     }        //弹出栈顶int size()  { return t+1;}            //栈内元素的数量int empty() {return t==-1 ? 1:0; }   //若栈为空返回1
}st;
int main(){char x;while(cin>>x){   //循环输入if(x=='@') break;       //输入为@停止;if(x=='(') st.push(x);  //左括号入栈if(x==')'){             //遇到一个右括号if(st.empty()) {cout<<"NO";return 0;} //栈空,没有左括号与右括号匹配else st.pop();      //匹配到一个左括号,出栈}}if(st.empty()) cout<<"YES"; //栈为空,所有左括号已经匹配到右括号,输出yeselse cout<<"NO";return 0;
}

STL:

#include<bits/stdc++.h> 
using namespace std;
string str;
stack<char> ops;
int main()
{cin >> str;long res = 0;for (int i = 0; i < str.length(); i++) {char c = str[i];if (c == '(') {ops.push(c);}else if (c == ')') {if (!ops.empty()) {ops.pop();}else {cout << "NO";return 0;}}}if (!ops.empty()) {cout << "NO";return 0;}cout << "YES";return 0;
}

Java代码

import java.util.Scanner;
public class Main {static final int N = 300008;static class mystack {int[] a = new int[N];int t = -1;void push(int data) {  a[++t] = data;    }int top() {   return a[t];        }void pop(){   if(t > -1) t--;     }int size(){   return t + 1;       }boolean  empty() {   return t == -1 ? true : false; }}public static void main(String[] args) {Scanner sc = new Scanner(System.in);mystack st = new mystack();String s = sc.next();for (int i = 0; i < s.length(); i++) {char x = s.charAt(i);if(x == '@') break;if(x == '(') st.push(x);if(x == ')') {if(st.empty()) {System.out.println("NO");return;}else st.pop();}}if(st.empty()) System.out.println("YES");else System.out.println("NO");}
}

Python代码

Python的手写栈用到了list。用list模拟栈有一个好处,不用担心栈空间不够大,因为list自动扩展空间。而且list的栈操作非常快,因为栈顶是list的末尾元素,栈只有一个出入口,只在list的末尾进行进栈和出栈操作,操作极为快捷。下面是list实现的栈功能。

在这里插入图片描述

下面是例题的Python代码,栈用list模拟。

st = []             #定义栈,用list实现
flag =  True        #判断左括号和右括号的数量是否一样多
s = input().strip()
for x in s:if x=='(':  st.append("(")    #进栈if x==")":if len(st)!=0:            #len():栈的长度st.pop()              #出栈,也可以写成 del st[-1] ,st[-1]是栈顶else:                     #栈已空,没有匹配的左括号flag = Falsebreak
if len(st)==0 and flag:  print('YES')
else:                    print('NO')

2.2 C++STL栈

竞赛时一般不自己手写栈,而是用STL stack:https://wyqz.top/p/870124582.html#toc-heading-9。

STL stack的主要操作见下表。

在这里插入图片描述
用下面的例题说明STLqueue的应用

例题:排列

题解:

把符合条件的一对<i, j>称为一个“凹”。首先模拟检查“凹”,了解执行的过程。以“3 1 2 5”为例,其中的“凹”有:“3-1-2”和“3-1-2-5”;还有相邻的“3-1”、“1-2”、“2-5”。一共5个“凹”,总价值13。

像“3-1-2”和“3-1-2-5”这样的“凹”,需要检查连续3个以上的数字。

例如“3 1 2”,从“3”开始,下一个应该比“3”小,例如“1”,再后面的数字比“1”大,才能形成“凹”。

再例如“3-1-2-5”,前面的“3-1-2”已经是“凹”了,最后的“5”也会形成新的“凹”,条件是这个“5”必须比中间的“1-2”大才行。

总结上述过程是:先检查“3”;再检查“1”符合“凹”;再检查“2”,比前面的“1”大,符合“凹”;再检查“5”,比前面的“2”大,符合“凹”。

以上是检查一个“凹”的两头,还有一种是“嵌套”。一旦遇到比前面小的数字,那么以这个数字为头,可能形成新的“凹”。例如“6 4 2 8”,其中的“6-4-2-8”是“凹”,内部的“4-2-8”也是凹。如果学过递归、栈,就会发现这是嵌套,所以本题用栈来做很合适。

以“6 4 2 8”为例,用栈模拟找“凹”。当新的数比栈顶的数小,就进栈;如果比栈顶的数大,就出栈,此时找到了一个“凹”并计算价值。下图中的圆圈数字是数在数组中的下标位置,用于计算题目要求的价值。

在这里插入图片描述
图(1):6进栈。
图(2):4准备进栈,发现比栈顶的6小,说明可以形成凹,4进栈。
图(3):2准备进栈,发现比栈顶的4小,说明可以形成凹,2进栈。
图(4):8准备进栈,发现比栈顶的2大,这是一个凹“4-2-8”,对应下标“②–④”,弹出2,然后计算价值,j-i+1=④-②+1=3。
图(5):8准备进栈,发现比栈顶的4大,这是一个凹“6-4-8”,对应下标“①–④”,弹出4,然后计算价值,j-i+1=④-①+1=4。
图(6):8终于进栈了,数字也处理完了,结束。

在上述过程中,只计算了长度为3和3以上的凹,并没有计算题目中“(3)a[i]-a[j]之间不存在其他数字”的长度为2的凹,所以最后统一加上这种情况的价值(n-1)×2 = 6。

最后统计得“6 4 2 8”的总价值是3+4+6=13。

C++代码

#include <bits/stdc++.h>
using namespace std;
const int N = 300008;
int a[N];                 //这里a[]是题目的数字排列
int main(){int n;  cin>>n;for(int i = 1;i <= n;i++)  cin>>a[i];   //输入数列stack <int> st;                   //定义栈long long ans = 0;for(int i = 1;i <= n;i++){while(!st.empty() && a[st.top()] < a[i]){st.pop();if(!st.empty()){int last = st.top();ans += (i - last + 1);}}st.push(i);}ans += (n - 1) * 2;              //(3)a[i]-a[j]之间不存在其他数字的情况cout<<ans;
}

2.3 Java 栈

Java Stack https://docs.oracle.com/en/java/javase/14/docs/api/java.base/java/util/Stack.html

有以下操作。

在这里插入图片描述

例题 排列 的Java代码。

import java.util.Scanner;
import java.util.Stack;
public class Main {static final int N = 300008;public static void main(String[] args) {Scanner sc = new Scanner(System.in);int n = sc.nextInt();int[] a = new int[N];for(int i = 1; i <= n; i++)  a[i] = sc.nextInt();        Stack<Integer> st = new Stack<>();long ans = 0;for(int i = 1; i <= n; i++) {while(!st.empty() && a[st.peek()] < a[i]) {st.pop();if(!st.empty()) {int last = st.peek();ans += (long)(i - last + 1);}}st.push(i);}ans += (n - 1) * 2;System.out.println(ans);}
}

2.4 Python栈

python的栈可以用以下三种方法实现:(1)list;(2)deque;(3)LifoQueue。比较它们的运行速度,list和deque一样快,而LifoQueue慢得多,建议使用list。前面已经介绍了用list实现栈的方法。

下面是例题 排列 的代码。

n = int(input())
a = [int(x) for x in input().split()]
st = []                                       #定义栈,用list实现
ans = 0
for i in range(n):while len(st) != 0 and a[st[-1]] < a[i]:  #st[-1]是栈顶st.pop()                              #弹出栈顶if len(st) != 0:last = st[-1]                     #读栈顶ans += (i - last + 1)st.append(i)                              #进栈
ans += (n - 1) * 2
print(ans)

3 习题

表达式括号匹配

表达式求值

小鱼的数字游戏

后缀表达式

【模板】栈

相关文章:

【蓝桥杯软件赛 零基础备赛20周】第6周——栈

文章目录 1. 基本数据结构概述1.1 数据结构和算法的关系1.2 线性数据结构概述1.3 二叉树简介 2. 栈2.1 手写栈2.2 CSTL栈2.3 Java 栈2.4 Python栈 3 习题 1. 基本数据结构概述 很多计算机教材提到&#xff1a;程序 数据结构 算法。 “以数据结构为弓&#xff0c;以算法为箭”…...

CWE/SANS TOP 25 2022

我整理了CWE/SANS TOP25 2022年的这25类缺陷&#xff0c;分类适合的开发语言&#xff0c;其实主要是C/C语言的缺陷相对于Java、PHP、Python、C#等更高级的语言的不同&#xff0c;所以分为适合C/C语言和其它语言。但是大家不要纠结&#xff0c;例如SQL难道C/C语言程序没有吗&…...

Qt 天气预报项目

参考引用 QT开发专题-天气预报 1. JSON 数据格式 1.1 什么是 JSON JSON (JavaScript Object Notation)&#xff0c;中文名 JS 对象表示法&#xff0c;因为它和 JS 中对象的写法很类似 通常说的 JSON&#xff0c;其实就是 JSON 字符串&#xff0c;本质上是一种特殊格式的字符串…...

新知识-Tuple元组的使用

文章目录 前言一、tuple元组是什么&#xff1f;二、解决方法总结 前言 这次碰到一个需求&#xff0c;大致需要把表A中的字段1和字段2作为共同的表去查表B&#xff0c;并且一次性需要查多条&#xff0c;一开始是想的是根据字段1和字段2去查然后循环多次&#xff0c;但是这样反复…...

“此应用专为旧版android打造,因此可能无法运行”,问题解决方案

当用户在Android P系统上打开某些应用程序时&#xff0c;可能会弹出一个对话框&#xff0c;提示内容为&#xff1a;“此应用专为旧版Android打造&#xff0c;可能无法正常运行。请尝试检查更新或与开发者联系”。 随着Android平台的发展&#xff0c;每个新版本通常都会引入新的…...

【Leetcode题单】(01 数组篇)刷题关键点总结03【数组的改变、移动】

【Leetcode题单】&#xff08;01 数组篇&#xff09;刷题关键点总结03【数组的改变、移动】&#xff08;3题&#xff09; 数组的改变、移动453. 最小操作次数使数组元素相等 Medium665. 非递减数列 Medium283. 移动零 Easy 大家好&#xff0c;这里是新开的LeetCode刷题系列&…...

Lag-Llama:基于 LlaMa 的单变量时序预测基础模型

文章构建了一个通用单变量概率时间预测模型 Lag-Llama&#xff0c;在来自Monash Time Series库中的大量时序数据上进行了训练&#xff0c;并表现出良好的零样本预测能力。在介绍Lag-Llama之前&#xff0c;这里简单说明什么是概率时间预测模型。概率预测问题是指基于历史窗口内的…...

vue3 :deep() 深度选择器不生效

vue3 :deep() 深度选择器不生效 问题出在根节点上&#xff0c;如果没有这个根节点&#xff0c;那么:deep()不起作用&#xff0c;我把根节点加上&#xff0c;:deep()样式就生效了。在组件外加个 就生效了 参考&#xff1a; 添加链接描述...

从零构建属于自己的GPT系列1:数据预处理(文本数据预处理、文本数据tokenizer、逐行代码解读)

&#x1f6a9;&#x1f6a9;&#x1f6a9;Hugging Face 实战系列 总目录 有任何问题欢迎在下面留言 本篇文章的代码运行界面均在PyCharm中进行 本篇文章配套的代码资源已经上传 从零构建属于自己的GPT系列1&#xff1a;文本数据预处理 从零构建属于自己的GPT系列2&#xff1a;语…...

c++中函数的引用

函数中的引用 引用可以作为函数的形参 不能返回局部变量的引用 #include<iostream> #include<stdlib.h> using namespace std; //形参是引用 void swap(int *x, int *y)//*x *y表示对x y取地址 { int tmp *x; *x *y; *y tmp; } void test01() { …...

IDA常用操作、快捷键总结以及使用技巧

先贴一张官方的图&#xff0c;然后我再总结一下&#xff0c;用的频率比较高的会做一些简单标注 快捷键 F系列【主要是调试状态的处理】 F2 添加/删除断点F4 运行到光标所在位置F5 反汇编F7 单步步入F8 单步跳过F9 持续运行直到输入/断点/结束 shift系列【主要是调出对应的页…...

Kibana使用指南

使用介绍主要特点应用场景数据可视化还有哪些类型安装步骤安装配置参数Elasticsearch配置参数注意事项 使用介绍 Kibana是一个开源的分析与可视化平台&#xff0c;设计出来用于和Elasticsearch一起使用的。可以用Kibana搜索、查看、交互存放在Elasticsearch索引里的数据&#…...

wvp如果确认音频udp端口开放成功

用到工具 在服务器上开启端口监听 选中udp server&#xff0c;点击创建按钮 设置服务器监听端口 在客户端连接服务器端口 选中udp客户端&#xff0c;点击创建 输入服务器地址 远程端口和本地端口&#xff0c;本地端口只要没被占用都可以使用 &#xff0c;点击确认 发送数据 …...

C#文件夹基本操作(判断文件夹是否存在、创建文件夹、移动文件夹、删除文件夹以及遍历文件夹中的文件)

目录 一、判断文件夹是否存在 1.Directory类的Exists()方法 2. DirectoryInfo类的Exists属性 二、创建文件夹 1. Directory类的CreateDirectory()方法 2.DirectoryInfo类的Create()方法 三、移动文件夹 1. Directory类的Move()方法 2.DirectoryInfo类的MoveT…...

python 交互模式和命令行模式的问题

python 模式的冲突 unexpected character after line continuation character 理论上 ide里&#xff0c;输入 python 文件路径\文件.py 就可以执行 但是有时候却报错 unexpected character after line continuation character 出现上述错误的原因是没有退出解释器&#x…...

计算机网络——数据链路层

目录 一、数据链路层的基本概念 &#xff08;一&#xff09;数据链路层的概念 &#xff08;二&#xff09;帧 &#xff08;三&#xff09;数据链路层分为哪两个部分 &#xff08;1&#xff09;LLC&#xff08;逻辑控制访问&#xff09; &#xff08;2&#xff09;MAC&…...

【限时免费】20天拿下华为OD笔试之【哈希集合】2023B-明明的随机数【欧弟算法】全网注释最详细分类最全的华为OD真题题解

文章目录 题目描述与示例题目描述输入描述输出描述&#xff1a;示例 1输入输出说明 解题思路代码PythonJavaC时空复杂度 华为OD算法/大厂面试高频题算法练习冲刺训练 题目描述与示例 题目描述 明明生成了N 个 1 至 500 之间的随机整数。请你删去其中重复的数字&#xff0c;即…...

播放器开发(五):视频帧处理并用SDL渲染播放

目录 学习课题&#xff1a;逐步构建开发播放器【QT5 FFmpeg6 SDL2】 步骤 VideoOutPut模块 1、初始化【分配缓存、读取信息】 2、开始线程工作【从队列读帧->缩放->发送渲染信号到窗口】 VideoWidget自定义Widget类 1、定义内部变量 2、如果使用SDL&#xff0c;需要进…...

Spring MVC数据绑定的几种方法(一)

这篇文章包含spring mvc的默认数据类型绑定和简单数据类型绑定。内容来自实验。 准备&#xff1a; &#xff08;1&#xff09;在IDEA环境中从archetye创建webapp类型的maven项目exp6。 &#xff08;2&#xff09;在src\main目录下创建并标注java源代码文件夹和resources资源文…...

CSP-坐标变换(其二)

问题描述 对于平面直角坐标系上的坐标 (x,y)&#xff0c;小 P 定义了如下两种操作&#xff1a; 拉伸 k 倍&#xff1a;横坐标 x 变为 kx&#xff0c;纵坐标 y 变为 ky&#xff1b; 旋转 θ&#xff1a;将坐标 (x,y) 绕坐标原点 (0,0) 逆时针旋转 θ 弧度&#xff08;0≤θ<…...

C++初阶-list的底层

目录 1.std::list实现的所有代码 2.list的简单介绍 2.1实现list的类 2.2_list_iterator的实现 2.2.1_list_iterator实现的原因和好处 2.2.2_list_iterator实现 2.3_list_node的实现 2.3.1. 避免递归的模板依赖 2.3.2. 内存布局一致性 2.3.3. 类型安全的替代方案 2.3.…...

Appium+python自动化(十六)- ADB命令

简介 Android 调试桥(adb)是多种用途的工具&#xff0c;该工具可以帮助你你管理设备或模拟器 的状态。 adb ( Android Debug Bridge)是一个通用命令行工具&#xff0c;其允许您与模拟器实例或连接的 Android 设备进行通信。它可为各种设备操作提供便利&#xff0c;如安装和调试…...

【WiFi帧结构】

文章目录 帧结构MAC头部管理帧 帧结构 Wi-Fi的帧分为三部分组成&#xff1a;MAC头部frame bodyFCS&#xff0c;其中MAC是固定格式的&#xff0c;frame body是可变长度。 MAC头部有frame control&#xff0c;duration&#xff0c;address1&#xff0c;address2&#xff0c;addre…...

在鸿蒙HarmonyOS 5中实现抖音风格的点赞功能

下面我将详细介绍如何使用HarmonyOS SDK在HarmonyOS 5中实现类似抖音的点赞功能&#xff0c;包括动画效果、数据同步和交互优化。 1. 基础点赞功能实现 1.1 创建数据模型 // VideoModel.ets export class VideoModel {id: string "";title: string ""…...

关于nvm与node.js

1 安装nvm 安装过程中手动修改 nvm的安装路径&#xff0c; 以及修改 通过nvm安装node后正在使用的node的存放目录【这句话可能难以理解&#xff0c;但接着往下看你就了然了】 2 修改nvm中settings.txt文件配置 nvm安装成功后&#xff0c;通常在该文件中会出现以下配置&…...

定时器任务——若依源码分析

分析util包下面的工具类schedule utils&#xff1a; ScheduleUtils 是若依中用于与 Quartz 框架交互的工具类&#xff0c;封装了定时任务的 创建、更新、暂停、删除等核心逻辑。 createScheduleJob createScheduleJob 用于将任务注册到 Quartz&#xff0c;先构建任务的 JobD…...

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…...

mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包

文章目录 现象&#xff1a;mysql已经安装&#xff0c;但是通过rpm -q 没有找mysql相关的已安装包遇到 rpm 命令找不到已经安装的 MySQL 包时&#xff0c;可能是因为以下几个原因&#xff1a;1.MySQL 不是通过 RPM 包安装的2.RPM 数据库损坏3.使用了不同的包名或路径4.使用其他包…...

C++.OpenGL (20/64)混合(Blending)

混合(Blending) 透明效果核心原理 #mermaid-svg-SWG0UzVfJms7Sm3e {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-icon{fill:#552222;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-text{fill…...

Golang——6、指针和结构体

指针和结构体 1、指针1.1、指针地址和指针类型1.2、指针取值1.3、new和make 2、结构体2.1、type关键字的使用2.2、结构体的定义和初始化2.3、结构体方法和接收者2.4、给任意类型添加方法2.5、结构体的匿名字段2.6、嵌套结构体2.7、嵌套匿名结构体2.8、结构体的继承 3、结构体与…...