数据结构(其二)--线性表(其二)

news2024/9/20 14:57:49

目录

5.栈

5.1 栈的基本操作

 5.2 各种栈

(1).顺序栈

        i.普通顺序栈

        ii.共享栈

        iii.关于销毁

(2).链栈

6.队列

6.1 队列的基本操作

6.2 各种队列

(1).循环队列

        i.代码

        ii.另外一种写法

(2).链式队列

        i.代码

(3).双端队列

7.栈在括号匹配中的应用

       i.主要思路

       ii.代码

8.栈在表达式求值中的应用

       (1).中缀表达式

        (2).前缀表达式

        (3).后缀表达式

        i.中缀转后缀,

        ii.后缀的运算(手算)

        iii.中缀转前缀

        iiii.前缀的运算(手算)

        iiiii.中缀转后缀(机算)

9.栈在递归中的应用

10.队列的应用(以后会学到)


5.栈

        栈(Stack)是一种允许在一端进行插入和删除的线性表

        特点:先入栈的元素,后出栈。(LIFO:Lost in,First out)

        空栈:没有数据元素的栈。

        栈顶:允许进行插入与删除的一端。

        栈底:不可进行操作的一端,除非栈底也是栈顶。

        出栈序列的种类数:
        

        n 指栈中的元素个数

5.1 栈的基本操作

*

InitStack(&S):初始化栈,创造一个空栈,分配内存

DestoryStack(&S):销毁栈,释放栈占用的内存空间。

*

Push(&S, x):进栈,若S栈未满,则加入x 并使之成为新栈顶。——————————增

Pop(&S, &x):出栈,若S栈非空,则弹出栈顶元素,并将之返回。--------------------------删

*

GetTop(S, &x):读取栈顶元素,若S栈非空,则用x返回栈顶元素。(不删除元素)----查

*

StackEmpty(S):判断一个栈是否为空。为空,则返回true;反之,返回false.

 5.2 各种栈

(1).顺序栈

        i.普通顺序栈

        顺序储存——数组

#define MaxSize 10	//
//顺序栈
class SqStack           //sequence stack
{
public:
	int data[MaxSize];	//静态数组存放栈元素
	int top;			//栈顶指针,储存栈顶的数组下标
};

//初始化
void InitStack(SqStack& S)
{
	S.top = -1;			//初始化栈顶指针
}
//判断栈是否为空
bool StackEmpty(SqStack S)
{
	if (S.top == -1)
		return true;
	else
		return false;
}
//进栈
bool Push(SqStack& S, int x)
{
	if (S.top == MaxSize - 1)
		return false;		//栈已满,报错
	S.data[++S.top] = x;	//此代码等同于下文两行代码
	//S.top = S.top + 1;
	//S.data[S.top] = x;
	return true;
}
//出栈
bool Pop(SqStack& S, int& x)
{
	if (S.top == -1)
		return false;	//栈为空,报错
	x = S.data[S.top--];//与下文两行代码相同
	//x = S.data[S.top];	
	//S.top--;			//将栈顶减一,即为删除了
	return true;
}
//读取(几乎与出栈相同)
bool GetTop(SqStack& S, int& x)
{
	if (S.top == -1)
		return false;	//栈为空,报错
	x = S.data[S.top];
	return true;
}

         对于top 指针,它还可以指向储存数据的下一位,此时,判断的依据就是 top == 0,进出栈时++、--的顺序也要发生改变,栈满条件:top == MaxSize

        ii.共享栈

        两个栈共享同一片内存(也是顺序储存方式),用于节省内存,一般两个栈分别起始于这片内存的两端,因此,栈满条件就变成了top_0 + 1 == top_1

#define MaxSize 10
//共享栈
class ShStack
{
public:
	int data[MaxSize];
	int top_0;			//0号栈顶指针
	int top_1;			//1号
};
//初始化
void InitStack(ShStack& S)
{
	S.top_0 = -1;
	S.top_1 = MaxSize;
}
//其他操作

        iii.关于销毁

        销毁主要分为两步:

        · 逻辑上的清空

        · 内存的回收

        第一步,就是对 top 的处理;第二步,因为储存用的是数组,数组在运行结束之后会由系统自动回收,所以第二步并没有具体的步骤。

(2).链栈

        用链式储存结构进行储存。

        在上一节中(数据结构(其二)--线性表(其一))单链表的建立,其中的头插法就是一种对链栈的处理。

        主要函数的代码(可运行)

#include<iostream>
using namespace std;

#define MaxSize 10
//链栈
class LinkNode
{
public:
	int data;
	LinkNode* next;
};
using LiStack = LinkNode*;

//初始化(带头结点)
void InitLink(LiStack& S)
{
	S = new LinkNode();
	if (S == nullptr)
		cout << "内存分配失败" << endl;
	S->data = 0;
	S->next = nullptr;
	cout << "初始化成功" << endl;		//检验代码是否可行
}
//初始化(不带头结点)
void InitLink1(LiStack& S)
{
	S = nullptr;
}
//判断空栈(带头结点)
bool Empty(LiStack S)
{
	if (S->next == nullptr)
		return true;
	return false;
}
//判断空栈(不带头结点)
bool Empty1(LiStack S)
{
	if (S == nullptr)
		return true;
	return false;
}
//判断栈满
bool Full(LiStack S)
{
	cout << "满不了一点" << endl;
	return true;
}

//进栈(带头结点)
bool PushLink(LiStack& S, int x)
{
	LinkNode* p = new LinkNode();
	if (p == nullptr)
		return false;
	p->data = x;
	p->next = S->next;
	S->next = p;
	return true;
}
//进栈(不带头结点)
bool PushLink1(LiStack& S, int x)
{
	LinkNode* p = new LinkNode();
	if (p == nullptr)
		return false;
	p->data = x;
	p->next = S;
	S = p;
	return true;
}

//出栈(带头结点)
bool PopLink(LiStack& S, int& x)
{
	if (S->next == nullptr)
		return false;			//栈为空
	LinkNode* p = S->next;
	x = p->data;
	S->next = p->next;
	delete p;
	return true;
}
//出栈(不带头结点)
bool PopLink1(LiStack& S, int& x)
{
	if (S->next == nullptr)
		return false;			//栈为空
	LinkNode* p = S;
	x = p->data;
	S = p->next;
	delete p;
	return true;
}
//打印(带头结点)
void PrintLNode(LiStack S)
{
	LinkNode* p = S->next;
	int i = 1;
	while (p != nullptr)
	{
		
		cout << "第" << i << "个元素:" << p->data << endl;
		i++;
		p = p->next;
	}
	cout << "___________________________" << endl;
}
//打印(不带头结点)
void PrintLNode1(LiStack S)
{
	LinkNode* p = S;
	int i = 1;
	while (p != nullptr)
	{

		cout << "第" << i << "个元素:" << p->data << endl;
		i++;
		p = p->next;
	}
	cout << "___________________________" << endl;
}
//获取栈顶元素(带头结点)
int GetTop(LiStack S)
{
	int a = -1;
	if (S->next == nullptr)
		return -999;			//指示空栈
	a = S->next->data;
	return a;
}
//获取栈顶元素(不带头结点)
int GetTop1(LiStack S)
{
	int a = -1;
	if (S == nullptr)
		return -999;			//指示空栈
	a = S->data;
	return a;
}
//测验
void test01()
{
	LiStack S;
	InitLink(S);
	int a;				//接收出栈元素

	//进栈
	PushLink(S, 1);
	PushLink(S, 2);
	PushLink(S, 3);		//逻辑上,这个是栈顶元素
	PrintLNode(S);
	//出栈
	PopLink(S, a);
	cout << "出栈元素a:" << a << endl;
	PrintLNode(S);
	//获取
	cout << "获取栈顶:" << GetTop(S) << endl;
}

int main()
{
	test01();

	system("pause");
	return 0;
}

6.队列

        队列(Queue)是一种只允许在一端插入、在另一端删除的线性表

        特点:先入队的元素,也会先出队列。(FIFO)

        队头:允许进行删除的一端,称为队头。

        队尾:允许进行插入的一端,称为队尾。

6.1 队列的基本操作

*

InitQueue(&Q):初始化

DestroyQueue(&Q):销毁队列,释放内存。

*

EnQueue(&Q, x):入队,若队列未满,则加入x,成为新的队尾。

DeQueue(&Q, &x):出队,若队列非空,则删除队头,并用x返回。

*

GetHead(Q, &x):读取队头元素,将队头元素用x 传递出来。

*

QueueEmpty(Q):判断队列是否为

6.2 各种队列

(1).循环队列

        数组实现。

        队指针指向 data[0];

        队指针指向存有数据的下一位,队尾指向的永远是的。(借此,进行队列是否已满的检测)

        之所以,称为循环,是因为在入队操作的逻辑中,使用了取余的思想(将无限的数据域控制在有限的范围中)。

        i.代码

#include<iostream>
using namespace std;

#define MaxSize 10
//队列——顺序
class SqQueue
{
public:
	int data[MaxSize];
	int front, rear;	//队头(front)与队尾指针,储存对应下标
	//int size;			//指示长度,此变量依据实际情况添加,有此变量,则可以充分利用内存,无需再牺牲一个单元内存来指示是否已满
	//int tag;			//指示最近一次的操作是删除(0)还是插入(1),也是可以充分利用内存,只有删除(tag==0)时,会使队列为空,只有插入(tag==1)时,会使队列已满,借此再根据两个指针的位置关系判别
};
//初始化
void InitQueue(SqQueue& Q)
{
	Q.front = Q.rear = 0;
	//Q.size = 0;		//若添加了size,之后的函数都要发生一定的变化,不过,本身的逻辑并不会发生多大的变化
	//Q.tag = 0;		//无需与size同时存在
}
//判断空
bool QueueEmpty(SqQueue Q)
{
	if (Q.front == Q.rear)
		return true;
	return false;
}
//判断满
bool QueueFull(SqQueue Q)
{
	if ((Q.rear + 1) % MaxSize == Q.front)	//由此,会牺牲一个单元内存,该内存中不会存储数据
		return true;
	return false;
}

//入队
bool EnQueue(SqQueue& Q, int x)
{
	if (QueueFull(Q))
		return false;
	Q.data[Q.rear] = x;
	Q.rear = (Q.rear + 1) % MaxSize;		//队列指针后移的独特运算方法,太妙了,因为有了模运算,所以其后移也可以做到循环
	return true;

}
//出队
bool DeQueue(SqQueue& Q, int& x)
{
	if (QueueEmpty(Q))
		return false;
	x = Q.data[Q.front];
	Q.front = (Q.front + 1) % MaxSize;		//因为是数组存储,所以不需要额外的释放操作
	return true;
}
//获取元素
bool GetHead(SqQueue Q, int& x)
{
	if (QueueEmpty(Q))
		return false;
	x = Q.data[Q.front];
	return true;
}
//获取元素个数
int GetLength(SqQueue Q)
{
	return((Q.rear + MaxSize - Q.front) % MaxSize);	//队列的长度计算公式
}
//打印全队列
bool PrintQueue(SqQueue Q)
{
	if (QueueEmpty(Q))
		return false;
	int i = Q.front;
	int cont = 1;
	while (i != Q.rear)
	{
		cout << "第" << cont << "个数是:" << Q.data[i] << endl;
		i++;
		cont++;
	}
	cout << "当前元素个数:" << GetLength(Q) << endl;
	cout << "-------------------" << endl;
	return true;
}
//测验
void test01()
{
	SqQueue q;
	InitQueue(q);

	cout << "当前元素个数:" << GetLength(q) << endl;
	//入队
	EnQueue(q, 1);
	EnQueue(q, 2);
	EnQueue(q, 3);
	PrintQueue(q);
	//出队
	int a;
	DeQueue(q, a);
	cout << "出队元素:" << a << endl;
	PrintQueue(q);
}
int main()
{
	test01();

	system("pause");
	return 0;
}

        ii.另外一种写法

        rear 指向data 的最后一位元素,而非其下一位了。

        那么,其队列的各个函数就要发生一些变化。        

        的判断标准:(Q.rear + 1) % MaxSize == Q.front。

        初始化:rear = MaxSize - 1;即零的前一位,如此方便插入。

        插入rear 指针,进行数据的赋值

        删除:也是类似。

Q.rear = (Q.rear + 1) % MaxSize;

Q.data[Q.rear] = x;

        的判断方法:

        方法一牺牲一个存储单元,使得front的前一个位置不能存放数据,则当(Q.rear + 2) % MaxSize == Q.front;时,即为满。

        方法二引入一个记录的变量,如size,tag等。

(2).链式队列

        i.代码

        值得注意:

        · 链式队列的类的定义,有两个

#include<iostream>
using namespace std;

class LinkNode
{
public:
	int data;
	LinkNode* next;
};
//链式队列——记录一个链表只需要保存他的头指针即可
class LinkQueue
{
public:
	LinkNode* front, * rear;
};

//初始化(带头结点)
void InitQueue(LinkQueue& Q)
{
	Q.front = Q.rear = new LinkNode();
	Q.front->next = nullptr;
}
//初始化(不带头结点)
void InitQueue1(LinkQueue& Q)
{
	Q.front = nullptr;
	Q.rear = nullptr;
}

//判空(带头结点)
bool QueueEmpty(LinkQueue& Q)
{
	if (Q.front == Q.rear)
		return true;
	return false;
}
//判空(不带头结点)
bool QueueEmpty1(LinkQueue& Q)
{
	if (Q.front == Q.rear && Q.front == nullptr)
		return true;
	return false;
}


//入队(带头结点)(只能尾插)
bool EnQueue(LinkQueue& Q, int x)
{
	LinkNode* p = new LinkNode();
	p->data = x;
	p->next = nullptr;
	Q.rear->next = p;
	Q.rear = p;
	return true;
}
//入队(不带头结点)(只能尾插)
bool EnQueue1(LinkQueue& Q, int x)
{
	LinkNode* p = new LinkNode();
	p->data = x;
	p->next = nullptr;
	if (Q.front == nullptr)		//空队列时,无头结点,直接称为第一个结点
	{
		Q.front = p;
		Q.rear = p;
	}
	else
	{
		Q.rear->next = p;
		Q.rear = p;
	}
	return true;
}
//出队(带头结点)
bool DeQueue(LinkQueue& Q, int& x)
{
	if (Q.front == Q.rear)
		return false;
	LinkNode* p = Q.front->next;		//设置一个临时结点,指向队头
	x = p->data;
	Q.front->next = p->next;			//绕开队头结点
	if (Q.rear == p)					//如果队头结点就是队尾结点,那么还需要更新rear 指针
		Q.rear = Q.front;
	free(p);
	return true;
}
//出队(不带头结点)
bool DeQueue1(LinkQueue& Q, int& x)
{
	if (Q.front == Q.rear)
		return false;
	LinkNode* p = Q.front;
	x = p->data;
	Q.front = p->next;			
	if (Q.rear == p)
	{
		Q.front = nullptr;
		Q.rear = nullptr;
	}
	free(p);
	return true;
}
//链式队列不会有队满情况
//打印全队(带头结点)
bool PrintLQueue(LinkQueue Q)
{
	if (QueueEmpty(Q))
		return false;
	LinkNode* p = Q.front->next;
	int i = 1;
	while (1)
	{
		cout << "第" << i << "个元素:" << p->data << endl;
		if (p == Q.rear)
			break;
		p = p->next;
		i++;
	}
}
//打印全队(不带头结点)
bool PrintLQueue1(LinkQueue Q)
{
	if (QueueEmpty1(Q))
		return false;
	LinkNode* p = Q.front;
	int i = 1;
	while (1)
	{
		cout << "第" << i << "个元素:" << p->data << endl;
		if (p == Q.rear)
			break;
		p = p->next;
		i++;
	}
}

void test04()
{
	LinkQueue Q;
	InitQueue1(Q);

	//入队
	EnQueue1(Q, 1);
	EnQueue1(Q, 22);
	EnQueue1(Q, 333);
	PrintLQueue1(Q);
	//出队
	int a = 0;
	DeQueue1(Q, a);
	cout << "出队元素:" << a << endl;
	PrintLQueue1(Q);
}
int main()
{
	test04();

	system("pause");
	return 0;
}

(3).双端队列

        允许在从线性表的两端进行插入删除。 

        双端队列也会由此衍生一些变种,如下

        以上类型队列,在考研中,常考,给定输入的元素顺序,求合法的出队序列

        一般,首先,有出队的第一个元素判断队列中已有的元素,根据具体队列的插入删除性质来判断是否合法。 

7.栈在括号匹配中的应用

        用以处理复杂式子中的各种括号的配对{ [ ( ) ] }

       i.主要思路

        遇到括号就入栈,遇到括号就弹出栈顶,并与之进行匹配,成功则继续,失败则直接结束。

       ii.代码

#include<iostream>
using namespace std;

#define MaxSize 10	//
//顺序栈
class SqStack           //sequence stack
{
public:
	char data[MaxSize];	//静态数组存放栈元素
	int top;			//栈顶指针,储存栈顶的数组下标
};

//初始化
void InitStack(SqStack& S)
{
	S.top = -1;			//初始化栈顶指针
}
//判断栈是否为空
bool StackEmpty(SqStack S)
{
	if (S.top == -1)
		return true;
	else
		return false;
}
//进栈
bool Push(SqStack& S, char x)
{
	if (S.top == MaxSize - 1)
		return false;		//栈已满,报错
	S.data[++S.top] = x;	//此代码等同于下文两行代码
	//S.top = S.top + 1;
	//S.data[S.top] = x;
	return true;
}
//出栈
bool Pop(SqStack& S, char& x)
{
	if (S.top == -1)
		return false;	//栈为空,报错
	x = S.data[S.top--];//与下文两行代码相同
	//x = S.data[S.top];	
	//S.top--;			//将栈顶减一,即为删除了
	return true;
}


//括号匹配
bool bracketCheck(char str[], int length)	//length是传入数组的长度
{
	SqStack S;
	InitStack(S);
	for (int i = 0; i < length; i++)
	{
		if (str[i] == '(' || str[i] == '[' || str[i] == '{')
		{
			Push(S, str[i]);	//将扫描的左半边括号存入栈中
		}
		else
		{
			if (StackEmpty(S))	//如果是空栈,则匹配失败
				return false;
			char topElem;		//接收栈顶元素
			Pop(S, topElem);
			if (str[i] == ')' && topElem != '(')
				return false;
			if (str[i] == '[' && topElem != ']')
				return false;
			if (str[i] == '{' && topElem != '}')
				return false;
		}
	}
	return StackEmpty(S);		//最终,栈为空则说明匹配成功

8.栈在表达式求值中的应用

       (1).中缀表达式

        日常最常见的(最习惯的)就是中缀表达式,如下

(1+(3+4)*8)-1

        意为,加减乘除在式子之中。

        (2).前缀表达式

        前缀表达式,就是加减乘除排列在前面,如

+ a b

        (3).后缀表达式

        后缀表达式(逆波兰表达式)(此表达式应用更加广泛),即加减乘除在数字之后排列,如

a b + 就是 a+b,a b的配列顺序不可发生改变

        i.中缀转后缀

a + b - c => a b + c -

每一个子式,包括两个数一个运算符,子式还可以与其他数字、运算符组合构成新的子式,

其中a b +,就可以看作一个子式,其与c -构成了又一个式子

*

对于复杂的式子,如A + B - ( C * D + E) + F

遵循优先原则,先转换A + B,再向右依次转换,得到A B + C D * E + - F +

        ii.后缀的运算(手算)

        如上文中的A B + C D * E + - F +,从左往右找,到第一个运算符,则弹出此处之前的两个数(A B),进行对应的运算,再将所得的数存入其中,继续从左往右遍历,以此类推,得出最终结果。

        iii.中缀转前缀

        遵循优先原则,如

A + B * (C - D) - E / F

按照原则,可转换为

+ A - * B - C D / E F

        实际的转换结果可有很多形式,这些转换的原则,只是为了统一格式

        iiii.前缀的运算(手算)

        与后缀类似,只要从右往左遍历,其他雷同。(注意加减乘除的操作数顺序)

        iiiii.中缀转后缀(机算)

        机算的基本原则(有运算符、界限符会入栈、出栈,操作数会直接加入后缀表达式):


        · 遇到操作数,直接加入后缀表达式

        · 遇到界限符,遇到“(” 入栈,遇到 “)”则依次弹出栈内运算符,并加入后缀表达式,直到弹出“)”为止,在没遇到“)”之前,按正常的逻辑来,该弹的弹,该入的入,但是,所谓的逻辑是在括号的,也就是说,在“(”之前入栈的不遵循括号内的逻辑,如,括号外有个*,括号内遇到了-,此时并不会把括号外的那个* 弹出。

        · 遇到运算符,依次弹出栈中优先级高于或等于当前运算符的所有运算符,并加入后缀表达式,

        · 处理完所有字符之后,将栈中剩余的运算符依次弹出,若栈空则无需此操作

9.栈在递归中的应用

        在递归函数的调用中,其底层逻辑就是栈。

10.队列的应用(以后会学到)

        · 树的层次遍历

        · 图的广度优先遍历

        · 在操作系统的应用——多进程调用系统资源时,系统对这些进程的处理原则就是队列的思想,先来先服务(FCFS)

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

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

相关文章

滴滴官宣潘展乐为滴滴网约车“快”乐大使

近日&#xff0c;滴滴宣布邀请游泳运动员潘展乐成为滴滴出行网约车“快”乐大使&#xff0c;同时开展打车确定性体验攻坚计划&#xff0c;上线3分钟无车赔活动&#xff0c;为司机发放高温补贴、流水加速卡等多重奖励&#xff0c;共同为用户提供更快、更便捷的出行体验。 作为男…

机器学习-29-多变量异常检测在区域供热系统中的应用(实战)

参考多变量异常检测:工业数据分析中的异常检测技术 1 多变量异常检测 在工业数据分析需求中,异常检测是数据分析和监控(如系统操作错误、异常情况、潜在和实际故障等)的关键技术。与传统的单变量异常检测(逐一检查每个变量/指标)不同,多变量异常检测考虑了多个变量之间…

小程序准备上线,软件开发公司需要提供哪些资料给甲方?

&#x1f3c6;本文收录于《CSDN问答解惑-专业版》专栏&#xff0c;主要记录项目实战过程中的Bug之前因后果及提供真实有效的解决方案&#xff0c;希望能够助你一臂之力&#xff0c;帮你早日登顶实现财富自由&#x1f680;&#xff1b;同时&#xff0c;欢迎大家关注&&收…

基于N32L406的EasyLogger日志库移植教程

首先感谢作者 https://github.com/armink/EasyLogger EasyLogger 简介 EasyLogger是一款超轻量级(ROM<1.6K, RAM<0.3K)、高性能的 C/C 日志库&#xff0c;非常适合对资源敏感的软件项目&#xff0c;例如&#xff1a; IoT 产品、可穿戴设备、智能家居等等。相比 log4c…

掌握录屏软件的快捷录制技巧!2024最新推荐这四款屏幕录制软件~

你是否曾希望捕捉电脑屏幕上的精彩瞬间&#xff1f;无论是游戏剪辑、教学视频还是会议记录&#xff0c;屏幕录制已成为我们数字生活中不可或缺的一部分。 面对屏幕录制的挑战&#xff0c;选择一款合适的录屏软件至关重要。市场上的录屏软件种类繁多&#xff0c;从专业级到用户…

应用地址信息获取新技巧:Xinstall来助力

在移动互联网时代&#xff0c;应用获取用户地址信息的需求越来越普遍。无论是为了提供个性化服务&#xff0c;还是进行精准营销&#xff0c;地址信息都扮演着至关重要的角色。然而&#xff0c;如何合规、准确地获取这一信息&#xff0c;却是许多开发者面临的挑战。今天&#xf…

如何选择最佳Mac数据恢复程序?10大 Mac 数据恢复软件评测

当您的手机或相机已满时&#xff0c;Mac 将成为存储您的照片、视频、音乐和其他重要数据的数据管理器。 然而&#xff0c;一旦珍贵的数据因为意外删除或未知原因而丢失&#xff0c;您一定会感到非常难过。 幸运的是&#xff0c;这篇文章收集了适用于 Mac 的最佳数据恢复软件。…

超声波眼镜清洗机哪款好用?品质上等的超声波清洗机评选

对于佩戴眼镜的人来说&#xff0c;眼镜清洁是一个必须面对的问题。然而&#xff0c;简单地用眼镜布擦拭并不能彻底清洁眼镜&#xff0c;这种方法不仅可能无法清除所有的视力&#xff0c;还容易划伤镜片表面。相比之下&#xff0c;超声波清洗机的作用非常显着。它采用了不直接接…

[ACTF2020 新生赛]BackupFile1

打开题目 利用disearch扫描&#xff0c;发现源文件index.php.bak 下载下来 打开文件 代码审计&#xff0c;翻译一下 翻译代码为&#xff1a; <?php include_once "flag.php"; //这一行使用 include_once 函数来包含&#xff08;或插入&#xff09;另一个 PHP …

RabbitMQ docker部署,并启用MQTT协议

在Docker中部署RabbitMQ容器并启用MQTT插件的步骤如下&#xff1a; 一、准备工作 安装Docker&#xff1a; 确保系统上已安装Docker。Docker是一个开源的容器化平台&#xff0c;允许以容器的方式运行应用程序。可以在Docker官方网站上找到适合操作系统的安装包&#xff0c;并…

xalpha,一个神奇的 Python 库!

更多资料获取 &#x1f4da; 个人网站&#xff1a;ipengtao.com 大家好&#xff0c;今天为大家分享一个神奇的 Python 库 - xalpha。 Github地址&#xff1a;https://github.com/refraction-ray/xalpha 在投资和金融分析领域&#xff0c;Python 语言因其强大的数据处理能力和…

集成经验模态分解 (EEMD) 及其在信号降噪中的应用

引言 在信号处理领域&#xff0c;处理非线性和非平稳信号是一个重要的挑战。经验模态分解 (EMD) 是一种有效的方法&#xff0c;但在处理带噪声的信号时&#xff0c;可能会出现模态混叠问题。集成经验模态分解 (Ensemble Empirical Mode Decomposition, EEMD) 作为EMD的改进方法…

Go语言+Vue3零基础入门全栈班09 Go语言+MongoDB开发用户管理系统API实战_20240730 课程笔记

概述 如果您没有Golang的基础&#xff0c;应该学习如下前置课程。 Golang零基础入门Golang面向对象编程Go Web 基础Go语言开发REST API接口_20240728Go语言操作MySQL开发用户管理系统API教程_20240729Redis零基础快速入门_20231227GoRedis开发用户管理系统API实战_20240730Mo…

PG如何实现跨大版本升级

数据库进行升级&#xff0c;是一个再正常不过的功能&#xff0c;比如功能的需要&#xff0c;遇到BUG&#xff0c;安全漏洞等等&#xff0c;具体升级包含子版本升级&#xff0c;主版本升级。如果用过ORACLE的朋友&#xff0c;一定知道&#xff0c;在ORACLE中&#xff0c;如果要实…

dp:221. 最大正方形

221. 最大正方形 看到这个题目真能立马想到dp吗&#xff1f;貌似很难&#xff0c;即使知道是一个dp题也很难想到解法。 直观来看&#xff0c;使用bfs以一个点为中点进行遍历&#xff0c;需要的时间复杂度为 O ( n 2 m 2 ) O(n^2m^2) O(n2m2) 但是可以很容易发现&#xff0c;…

昂科烧录器支持MindMotion灵动微电子的32位微控制器MM32SPIN360C

芯片烧录行业领导者-昂科技术近日发布最新的烧录软件更新及新增支持的芯片型号列表&#xff0c;其中MindMotion灵动微电子的32位微控制器MM32SPIN360C已经被昂科的通用烧录平台AP8000所支持。 MM32SPIN360C使用高性能的ARM CortexM0为内核的32位微控制器&#xff0c;5V输出的L…

九大原则,轻松构建个人高效SOP

1、原则一、工作汇报SOP SCQA模型(升职加薪的关键!&#xff09; 清晰定义问题和提出解决方案 类别 关键词 解读 S - Situation 情景 陈述项目背景&#xff0c;目标&#xff0c;愿景 C - Complication 冲突 讲卡点&#xff0c;讲冲突 Q - Question 疑问-问题 这些冲…

vue2 封装插槽组件

安装 element-ui npm install element-ui --save ---force main.js 导入 import Vue from vue; import ElementUI from element-ui; import element-ui/lib/theme-chalk/index.css; import App from ./App.vue; Vue.use(ElementUI); new Vue({ el: #app, render: h > h(Ap…

未来RPA财税的发展前景

近年来&#xff0c;全球数字化进程持续提速&#xff0c;越来越多企业受到效率及运营成本的压力&#xff0c;正努力寻求企业增长发展的新路径&#xff0c;而财务作为企业战略的“大脑”&#xff0c;成为企业数字化转型的重要突破口。RPA技术由于能够自动化各种重复性和繁琐的任务…

如何利用智能电子工牌提高酒店员工的服务技能和沟通效率?

智能电子语音工牌的基本功能 智能电子录音工牌通常集成了录音、语音识别、数据上传等功能&#xff0c;能够在员工与客户互动的过程中实时录制音频&#xff0c;并将数据上传到云端服务器。这些工牌还可能配备定位功能&#xff0c;以便追踪员工的位置和服务轨迹。通过语音识别技…