数据结构——栈,队列,及其结构特点应用。

news2024/12/22 20:55:46

 ​✅<1>主页:我的代码爱吃辣
📃<2>知识讲解:数据结构——栈,队列。
🔥<3>创作者:我的代码爱吃辣
☂️<4>开发环境:Visual Studio 2022
🏡<5>系统环境:windows 10
💬<6>前言:今天来学习一下,数据结构中的栈和队列的实现和应用。

目录

🦃一.栈

🐔(1)什么是栈

 🐣(2)栈的实现:

🌱(3).栈的应用

🌾二.队列

🌲(1)什么是队列

🌵 (2)队列的实现

 🍄(3)队列的应用:


🦃一.栈

🐔(1)什么是栈

栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶,另一端称为栈底。栈中的数据元素遵守后进先出LIFO(Last In First Out)的原则。

压栈:栈的插入操作叫做进栈/压栈/入栈,入数据在栈顶。
出栈:栈的删除操作叫做出栈,出数据也在栈顶。

 🐣(2)栈的实现:

栈的实现一般可以使用数组或者链表实现,相对而言数组的结构实现更优一些。因为数组在尾上插入数据的代价比较小。因为栈即插入和删除(入栈和出战栈)都是在线性表的尾部进行操作,数组的尾部的插如和删除的时间复杂度都是 O(1) ,而如果是链式结构,去实现栈结构,针对尾插和尾删的时间复杂度都是 O(n) ,而双向循环带头的链表,虽然可以解决这个问题,但是.......

我们将栈的实现分为以下各个部分:

1.栈的定义 (StactInit)

typedef int STDateType;  //数据类型
typedef struct Stact
{
	STDateType* date; //数组
	int capacity;   //栈的容量
	int top;      //栈内数据的个数
}ST;

ST* StactInit()
{
	ST* Stact = (ST*)malloc(sizeof(ST));  //创建栈的结构
    //栈的结构初始化
	Stact->capacity = 4; 
	Stact->top = 0;
	Stact->date = (STDateType*)malloc(sizeof(STDateType)*Stact->capacity);
    //返回栈
	return Stact;
}

2.栈的销毁 (StactDestroy)

void StactDestory(ST* Stact)
{
	assert(Stact);
	//先释放数组申请的空间
	free(Stact->date);
	Stact->date = NULL;
	Stact->capacity = 0;
	Stact->top = 0;
	//在释放栈的结构体空间
	free(Stact);
}

3.栈的StactPushBank操作 (入栈)

void StactPushBank(ST* Stact, STDateType x)
{
	//断言Stact,当进行Push时,栈结构必须存在(Stact!=NULL),
	//如果不存也就是栈是空(Stact==NULL),那Push的操作就是非法的
	assert(Stact);
	//每次对栈的底层是数组,所以每次都要检查是否需要扩容
	if (Stact->capacity == Stact->top)
	{
		STDateType* tmp = (STDateType*)realloc(Stact->date, Stact->capacity * 2);
		if (tmp==NULL)
		{
			perror("realloc");
			exit(-1);
		}
		Stact->date = tmp;
		Stact->capacity *= 2;
	}
	//将x入栈,数组的栈内数据的个数加一
	Stact->date[Stact->top++] = x;
}

4.栈的StactPopBank操作 (出栈)

void StactPopBank(ST* Stact)
{
	assert(Stact);
	//当栈已经空了,还去出栈就是非法了
	assert(!StactEmpty(Stact));  

	Stact->top--;
}

5.栈的 StactTop (得到栈顶元素)

STDateType StactTop(ST* Stact)
{
	assert(Stact);
	//当栈已经空了,无法获取栈顶元素
	assert(!StactEmpty(Stact));

	return Stact->date[Stact->top - 1];
}

6.栈的StactSize (元素个数)

int StactSize(ST* Stact)
{
	assert(Stact);
	
	return Stact->top;
}

7.栈的判空 (StactEmpty)

bool StactEmpty(ST* stact)
{
	assert(stact);
	//当栈内数据个数为0时,栈为空
	return stact->top == 0;
}

测试:

void Print(ST* Stact)
{
	assert(Stact);
	for (int i = 0; i < Stact->top; i++)
	{
		printf("%d ", Stact->date[i]);
	}
	printf("\n");
}
int main()
{
	ST* Stact= StactInit();
	StactPushBank(Stact, 100); 
	StactPushBank(Stact, 200); 
	StactPushBank(Stact, 300); 
	StactPushBank(Stact, 400); 
	Print(Stact);
	printf("StactSize:%d\n",StactSize(Stact));
	//Pop一次
	StactPopBank(Stact);
	Print(Stact);
	printf("StactSize:%d\n", StactSize(Stact));
	StactDestory(Stact);
	return 0;
}

🌱(3).栈的应用

(1)例题

若进栈序列为 1,2,3,4 ,进栈过程中可以出栈,则下列不可能的一个出栈序列是()
A 1,4,3,2
B 2,3,4,1
C 3,1,4,2
D 3,4,2,1

答案:C

分析:选项A,1进1出,2进3进4进,4出3出2出,所以出栈顺序1,4,3,2,选项A正确。

           选项B,1进2进,2出,3进3出,4进,4出1出,所以出栈顺序2,3,4,1,选项B正确。

           选项C,1进2进3进,3出,此时想要出2,就必须先出栈1,所以选项C错误。

           选项D,1进2进3进,3出,4进,4出2出1出,所以出栈顺序3,4,2,1,选项D正确。

(2)例题

LeetCode ———— 20. 有效的括号

题目描述:

 思路分析:

遇到左括号就进栈,遇到右括号就出栈,将出栈的左括号与右括号进行匹配,如果匹配成功就继续,如果匹配失败就返回false。

//栈结构
typedef char STDateType;
typedef struct Stact
{
	STDateType* date;
	int capacity;
	int top;
}ST;

ST* StactInit();

void StactPushBank(ST* Stact, STDateType x);

int StactSize(ST* Stact);

void StactDestory(ST* Stact);

void StactPopBank(ST* Stact);

STDateType StactTop(ST* Stact);

bool StactEmpty(ST* stact);


ST* StactInit()
{
	ST* Stact = (ST*)malloc(sizeof(ST));
	Stact->capacity = 4;
	Stact->top = 0;
	Stact->date = (STDateType*)malloc(sizeof(STDateType) * Stact->capacity);
	return Stact;
}

void StactPushBank(ST* Stact, STDateType x)
{
	assert(Stact);
	if (Stact->capacity == Stact->top)
	{
		STDateType* tmp = (STDateType*)realloc(Stact->date, Stact->capacity * 2);
		if (tmp == NULL)
		{
			perror("realloc");
			exit(-1);
		}
		Stact->date = tmp;
		Stact->capacity *= 2;
	}
	Stact->date[Stact->top++] = x;
}

bool StactEmpty(ST* stact)
{
	assert(stact);
	return stact->top == 0;
}

STDateType StactTop(ST* Stact)
{
	assert(Stact);
	assert(!StactEmpty(Stact));
	return Stact->date[Stact->top - 1];
}

void StactPopBank(ST* Stact)
{
	assert(Stact);
	assert(!StactEmpty(Stact));
	Stact->top--;
}

void StactDestory(ST* Stact)
{
	assert(Stact);
	free(Stact->date);
	Stact->date = NULL;
	Stact->capacity = 0;
	Stact->top = 0;
	free(Stact);
}

int StactSize(ST* Stact)
{
	assert(Stact);
	return Stact->top;
}

bool isValid(char* s) {
	//创建栈
	ST* stact = StactInit();
	while (*s)
	{
		//遇到左括号进栈
		if (*s == '(' || *s == '{' || *s == '[')
		{
			StactPushBank(stact, *s);
			s++;
		}
		else
		{	//遇到右括号出栈,如果出栈的括号时,
			//栈中已经空,此时括号匹配已经失败
			if (StactEmpty(stact))
			{
				StactDestory(stact);
				return false;
			}
			//如果栈不为空,出栈的左括号,与遇到的右括号匹配
			//如果匹配成功就,继续向后走,匹配失败就返回false
			char ch = StactTop(stact);
			StactPopBank(stact);
			if ((ch == '(' && *s == ')') ||
				(ch == '[' && *s == ']') ||
				 ch == '{' && *s == '}')
			{
				s++;
			}
			else
			{
				StactDestory(stact);
				return false;
			}
		}
	}
	//当括号匹配匹配完时,如果栈中还有括号,
	//也就意味着匹配失败。
	if (!StactEmpty(stact))
	{
		StactDestory(stact);
		return false;
	}
	StactDestory(stact);
	return true;
}

🌾二.队列

🌲(1)什么是队列

队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出FIFO(First In First Out) 入队列:进行插入操作的一端称为队尾 出队列:进行删除操作的一端称为队头。

🌵 (2)队列的实现

队列也可以数组和链表的结构实现,使用链表的结构实现更优一些,因为如果使用数组的结构,出队列在数组头上出数据,效率会比较低。

1.队列的定义——QueueInit

由于队列是,队尾入数据,队头出数据,为了方便数据的入队,我们除了队头指针,还会设计一个队尾指针。

typedef int QUDateType;
typedef struct QueueNode
{
	QUDateType date;
	struct QueueNode* next;
}QueueNode;

typedef struct Queue
{
	QueueNode* head;
	QueueNode* tail;
	int size;
}Queue;

void QueueInit(Queue* pque)
{
	assert(pque);
	pque->head = NULL;
	pque->tail = NULL;
	pque->size = 0;
}
int main()
{
	Queue Q;
	QueueInit(&Q);
	
	return 0;
}

2.入队操作——QueuePush

void QueuePush(Queue* pque,QUDateType x)
{
	//断言队列结构,当进行入队操作时,队列结构一定不能为空
	assert(pque);
	//申请空间
	QueueNode* newnode = (QueueNode*)malloc(sizeof(QueueNode));
	if (newnode == NULL)
	{
		perror("malloc");
		exit(-1);
	}
	//赋值
	newnode->date = x;
	newnode->next = NULL;
	//如果队列为空,此时入队的就是第一个数据,也将是队列的头尾数据
	if (pque->head == NULL)
	{
		pque->head = pque->tail = newnode;
	}
	//如果队列不为空,就将数据连接到队尾巴后面
	else
	{
		pque->tail->next = newnode;
		pque->tail = newnode;
	}
	//队列中数据个数加一
	pque->size++;
}

3.队列销毁——QueueDestroy

void QueueDestroy(Queue* pque)
{
	assert(pque);
	QueueNode* cur = pque->head;
	while (cur)
	{
		QueueNode* nextnode = cur->next;
		free(cur);
		cur = nextnode;
	}
	pque->head = pque->tail = NULL;
}

4.得到对头数据——QueueFront

QUDateType QueueFront(Queue*pque)
{
	assert(pque);
	assert(!QueueEmpty(pque));
	return pque->head->date;
}

5.队列判空——QueueEmpty

bool QueueEmpty(Queue* pque)
{
	assert(pque);
	return pque->head == NULL && pque->tail == NULL;
}

6.删除对头数据——QueuePop

void QueuePop(Queue* pque)
{
	assert(pque);   //队列结构不能为空
	assert(!QueueEmpty(pque));   //删除数据时队列不能为空 
	//队列中只有一个数据的时候
	if (pque->head->next == NULL)
	{
		free(pque->head);
		pque->tail = pque->head = NULL;
	}
	//队列中数据个数大于1
	else
	{
		QueueNode* popnode = pque->head;
		pque->head = pque->head->next;
		free(popnode);
	}
	//数据个数减一
	pque->size--;
}

7.得到队尾数据——QueueBack

QUDateType QueueBack(Queue* pque)
{
	assert(pque);
	assert(!QueueEmpty(pque));
	return pque->tail->date;
}

8.得到队列中数据个数——QueueSize


int QueueSize(Queue* pque)
{
	assert(pque);
	return pque->size;
}

测试:

int main()
{
	Queue Q;
	QueueInit(&Q);
	//插如100 .200 300 ,400 ,
	QueuePush(&Q, 100);
	QueuePush(&Q, 200);
	QueuePush(&Q, 300);
	QueuePush(&Q, 400);

	//输出队头数据
	printf("%d ", QueueFront(&Q));
	//输出队尾数据
	printf("%d ", QueueBack(&Q));
	//输出队列数据个数
	printf("%d \n", QueueSize(&Q));
	//输出队列中的数据
	while (!QueueEmpty(&Q))
	{
		printf("%d ", Q.head->date);
		QueuePop(&Q);
	}
	//队列销毁
	QueueDestroy(&Q);

	return 0;
}

 🍄(3)队列的应用:

LeetCode——225. 用队列实现栈

题目描述:

 思路:

每次入队数据都需要从不为空的队列进,这样可以保证

Push:进栈,对应到两个队列的操作就是,入不为空的队列。

Top:得到栈顶数据,对应到两个队列的操作就是,得到两个队列中不为空的队列的队尾数据。

Pop:删除栈顶数据,对应的两个队列的操作就是,删除不为空队列的队尾数据元素,但是由于队列结构的原因,要想删除队尾数据,就要先删除队尾前面的数据,所以我们可以先将队尾前面的数据放到另外一个空队列,再将队尾数据删除。

Empty:判断栈是否为空,对应的两个队列的操作就是,只有两个队列都已经没有数据时,栈才为空。

代码:

//队列结构
typedef int QUDateType;
typedef struct QueueNode
{
	QUDateType date;
	struct QueueNode* next;
}QueueNode;

typedef struct Queue
{
	QueueNode* head;
	QueueNode* tail;
	int size;
}Queue;

void QueueInit(Queue* pque)
{
	assert(pque);
	pque->head = NULL;
	pque->tail = NULL;
	pque->size = 0;
}
//进队列
void QueuePush(Queue* pque,QUDateType x)
{
	assert(pque);
	QueueNode* newnode = (QueueNode*)malloc(sizeof(QueueNode));
	if (newnode == NULL)
	{
		perror("malloc");
		exit(-1);
	}
	newnode->date = x;
	newnode->next = NULL;
	if (pque->head == NULL)
	{
		pque->head = pque->tail = newnode;
	}
	else
	{
		pque->tail->next = newnode;
		pque->tail = newnode;
	}
	pque->size++;
}
//队列为空
bool QueueEmpty(Queue* pque)
{
	assert(pque);

	return pque->head == NULL && pque->tail == NULL;
}
//得到对头数据
QUDateType QueueFront(Queue*pque)
{
	assert(pque);
	assert(!QueueEmpty(pque));
	return pque->head->date;
}
//得到队尾数据
QUDateType QueueBack(Queue* pque)
{
	assert(pque);
	assert(!QueueEmpty(pque));
	return pque->tail->date;
}
//队列数据个数
int QueueSize(Queue* pque)
{
	assert(pque);
	return pque->size;
}
//删除队头数据
void QueuePop(Queue* pque)
{
	assert(pque);
	assert(!QueueEmpty(pque));
	//队列中只有一个数据的时候
	if (pque->head->next == NULL)
	{
		free(pque->head);
		pque->tail = pque->head = NULL;
	}
	else
	{
		QueueNode* popnode = pque->head;
		pque->head = pque->head->next;
		free(popnode);
	}
	pque->size--;
}
//队列销毁
void QueueDestroy(Queue* pque)
{
	assert(pque);
	QueueNode* cur = pque->head;
	while (cur)
	{
		QueueNode* nextnode = cur->next;
		free(cur);
		cur = nextnode;
	}
	pque->head = pque->tail = NULL;
}
//封装两个队列
typedef struct {
    Queue q1;
    Queue q2;
} MyStack;

//创建栈
MyStack* myStackCreate() {
    MyStack*Q=(MyStack*)malloc(sizeof(MyStack));
    QueueInit(&Q->q1);
    QueueInit(&Q->q2);
    return Q;
}

//将元素 x 压入栈顶。
void myStackPush(MyStack* obj, int x) {
    //找到空队列与非空队列
    QueueNode*empty=&obj->q1;
    QueueNode*noempty=&obj->q2;
    if(!QueueEmpty(&obj->q1))
    {
        empty=&obj->q2;
        noempty=&obj->q1;
    }
    //将数据入空队列
    QueuePush(noempty,x);
}
//删除栈顶数据
int myStackPop(MyStack* obj) {
    assert(obj);
    //找到空队列与非空队列
    QueueNode*empty=&obj->q1;
    QueueNode*noempty=&obj->q2;
    if(!QueueEmpty(&obj->q1))
    {
        empty=&obj->q2;
        noempty=&obj->q1;
    }
    //将非空队列只留一个数据,其他的全部出队到空队列
    while(QueueSize(noempty)>1)
    {
        QueuePush(empty,QueueFront(noempty));
        QueuePop(noempty);
    }
    //返回非空队列的最后一个数据
    int ret=QueueFront(noempty);
    QueuePop(noempty);
    return ret;
}
//返回栈顶数据
int myStackTop(MyStack* obj) {
    assert(obj);
    QueueNode*empty=&obj->q1;
    QueueNode*noempty=&obj->q2;
    if(!QueueEmpty(&obj->q1))
    {
        empty=&obj->q2;
        noempty=&obj->q1;
    }
    return QueueBack(noempty);
}
//栈判空
bool myStackEmpty(MyStack* obj) {
    assert(obj);
    return QueueEmpty(&obj->q1)&&QueueEmpty(&obj->q2);
}
//销毁栈
void myStackFree(MyStack* obj) {
    assert(obj);
    QueueDestroy(&obj->q1);
    QueueDestroy(&obj->q2);
    free(obj);
}

 测试:

 2.LeetCode——622. 设计循环队列

 题目描述:

 思路:在设计循环队列的时候,我们可以使用数组,或者链表都是可以的,这里我们就使用数组来实现循环队列。

1.MyCircularQueue(结构)

typedef struct {

    int *date;
    //最后一个数据的下一个坐标
    int tail;
    //头指针
    int head;
    循环队列的容量
    int k;
} MyCircularQueue;

2.MyCircularQueue(k)(创建)

在设计循环队列的时候,我们设计队列的容量时多开一个容量,目的是为了更好的分清队空和队满,队空和队满的时候,头尾坐标都会指在同一位置上。

 

MyCircularQueue* myCircularQueueCreate(int k) {
    MyCircularQueue*Q=(MyCircularQueue*)malloc(sizeof(MyCircularQueue));
    Q->date=(int *)malloc(sizeof(int)*(k+1));
    Q->tail=0;
    Q->head=0;
    Q->k=k;
    return Q;
}

3.myCircularQueueEnQueue(入队)

bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {
    //先判断队列是否已经满了
    if(myCircularQueueIsFull(obj))
    {
        return false;
    }
    //断言判断队列结构
    assert(obj);
    //在队尾出数据
    obj->date[obj->tail++]=value;
    //当数据尾部已经在数组的最后了,此时在进入数据后,
    //数据尾巴下标时刻保持在数据尾部的后一个下标的,
    //就要回到数组的头部位置。
    if(obj->tail==(obj->k)+1)
    {
        obj->tail=0;
    }
    return true;
}

4.Front(获取对头数据)


int myCircularQueueFront(MyCircularQueue* obj) {
    assert(obj);
    //队列不为空,才可以获得数据
    if(myCircularQueueIsEmpty(obj))
    {
        return -1;
    }
    return obj->date[obj->head];
}

5.deQueue(删除对头数据)

bool myCircularQueueDeQueue(MyCircularQueue* obj) {
    assert(obj);
    //队列不能为空
    if(myCircularQueueIsEmpty(obj))
    {
        return false;
    }
    //如果head不在数组的尾部,直接head++
    obj->head++;
    //如果head,在数组的最后一个位置,此时head++以后需要循环到数组第一个位置
    if(obj->head==obj->k+1)
    {
        obj->head=0;
    }
    return true;
}

 

6.Rear(获得队尾数据)


int myCircularQueueRear(MyCircularQueue* obj) {
    assert(obj);
    //首先队列不能为空
    if(myCircularQueueIsEmpty(obj))
    {
        return -1;
    }
    //当数据尾在数组开头处,最后一个数据在数组的尾部
    //此时k就是数组的最后一个数据的下标
    if(obj->tail-1<0)
    {
        return obj->date[obj->k];
    }
    //如果数据尾部在数组中间或者是在数组尾部,数据尾部就是date[tail-1].
    return obj->date[obj->tail-1];
}

 7.isEmpty(判断队列是否为空)

bool myCircularQueueIsEmpty(MyCircularQueue* obj) {
    assert(obj);
    //头尾相等就是空。
    return obj->tail==obj->head;
}

8.isFull(判断队列是否满)

bool myCircularQueueIsFull(MyCircularQueue* obj) {
    assert(obj);
    //当tail在数组的最后一个位置时,head在数组第一个位置。
    //tail不在数据的最后。
    return (obj->tail+1)%(obj->k+1)==obj->head;
}

9. 销毁队列


void myCircularQueueFree(MyCircularQueue* obj) {
    assert(obj);
    free(obj->date);
    free(obj);
}

代码:

typedef struct {
    int *date;
    int tail;
    int head;
    int k;
} MyCircularQueue;

bool myCircularQueueIsEmpty(MyCircularQueue* obj);
bool myCircularQueueIsFull(MyCircularQueue* obj);

MyCircularQueue* myCircularQueueCreate(int k) {
    MyCircularQueue*Q=(MyCircularQueue*)malloc(sizeof(MyCircularQueue));
    Q->date=(int *)malloc(sizeof(int)*(k+1));
    Q->tail=0;
    Q->head=0;
    Q->k=k;
    return Q;
}

bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {
    
    if(myCircularQueueIsFull(obj))
    {
        return false;
    }
    assert(obj);
    obj->date[obj->tail++]=value;
    if(obj->tail==(obj->k)+1)
    {
        obj->tail=0;
    }
    return true;
}

bool myCircularQueueDeQueue(MyCircularQueue* obj) {
    assert(obj);
    if(myCircularQueueIsEmpty(obj))
    {
        return false;
    }
    obj->head++;
    if(obj->head==obj->k+1)
    {
        obj->head=0;
    }
    return true;
}

int myCircularQueueFront(MyCircularQueue* obj) {
    assert(obj);
    if(myCircularQueueIsEmpty(obj))
    {
        return -1;
    }
    return obj->date[obj->head];
}

int myCircularQueueRear(MyCircularQueue* obj) {
    assert(obj);
    if(myCircularQueueIsEmpty(obj))
    {
        return -1;
    }
    if(obj->tail-1<0)
    {
        return obj->date[obj->k];
    }
    return obj->date[obj->tail-1];
}

bool myCircularQueueIsEmpty(MyCircularQueue* obj) {
    assert(obj);
    return obj->tail==obj->head;
}

bool myCircularQueueIsFull(MyCircularQueue* obj) {
    assert(obj);
    return (obj->tail+1)%(obj->k+1)==obj->head;
}

void myCircularQueueFree(MyCircularQueue* obj) {
    assert(obj);
    free(obj->date);
    free(obj);
}

测试:

 🍂最后

要想改变我们的人生,第一步就是要改变我们的心态。只要心态是正确的,我们的世界就会的光明的。

 

 

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

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

相关文章

路由查找原理

最近在设计Netflow采集系统时&#xff0c;我想要将客户端的公网IP根据IP库转为对应的国家&#xff0c;此外在CACHE机房中&#xff0c;交换机上是没有AS信息的&#xff0c;因此我们也需要根据IP去查路由库&#xff0c;转换出AS信息。 这两个问题的本质是类似的&#xff0c;无论是…

棱镜七彩作为首批成员单位入选工信部网络安全产业发展中心重点实验室!

近日&#xff0c;工信部网络安全产业发展中心公布了网络安全技术与产业发展工信部重点实验室专项工作组成员单位名单。棱镜七彩首批入选&#xff0c;成为信息技术应用创新基础软硬件安全工作组的成员单位&#xff01; 为深入贯彻落实网络强国战略&#xff0c;充分发挥网络安全技…

FOC控制之小A小B小C是如何追求小D的

1、写在前面 随着电动汽车的热火&#xff0c;关于FOC控制技术的文章这几年在网络上可谓是一搜一大把&#xff0c;各种理论分析&#xff0c;公式推导&#xff0c;应有尽有。通过这些文章&#xff0c;可以看出大佬还是很多的。另外也有FOC的开源硬件。而在大几年前&#xff0c;第…

党务管理系统搭建,答题获积分,学习有好礼

党务管理系统搭建是以服务党员群众为目的的&#xff0c;然后通过互联网信息化手段&#xff0c;将党建工作与大数据等新技术融合&#xff0c;实现党建资源答题学习的数字化整合&#xff0c;也提升了党建科学化水平。 党务管理系统搭建助力党建数字化、规范化&#xff1a;利用信息…

快来生成你专属的英文名吧(使用字符级RNN)!

目录 一.前言 二.准备数据 三.构造神经网络 四.训练 五.网络采样&#xff08;预测&#xff09; 一.前言 数据集为18个国家的姓氏&#xff0c;任务是根据训练得到的模型&#xff0c;在给定国家类别和首字母后&#xff0c;能得到一个与该国人名非常相似的一个人名。 > …

openstack基本命令小结

文章目录Openstack0、进入1、查看日志日志位置日志格式举例2、CLI命令格式基本格式使用帮助3、命令文档&#xff08;常用&#xff09;4、基础组件的常用命令1、keystone查询类查看所有组件状态查看所有服务的状态查看域列表查看服务列表查看节点列表查询用户列表查询用户详细信…

用5G制造5G,中国电信打造“滨江模式”,助力电子信息制造产业升级

工业和信息化部近日印发《5G全连接工厂建设指南》&#xff0c;提出“十四五”时期&#xff0c;主要面向原材料、装备、消费品、电子等制造业&#xff0c;采矿、港口、电力等重点行业领域&#xff0c;加快5G全连接工厂建设。中国电信联合中兴通讯打造南京滨江智能工厂&#xff0…

Python第三方库之MedPy

1.MedPy简介 MedPy 是一个图像处理库和针对医学(如高维)图像处理的脚本集合&#xff0c;此处主要讨论利用该库计算常见的医学图像分割任务评价指标&#xff0c;如Dice、Jaccard、Hausdorff Distance、Sensitivity、Specificity、Positive predictive value等。 论文表格的表头…

docker部署的redis集群 添加节点(扩容)

上篇博文完成了在 docker 中部署 redis 多主多从集群&#xff1a;点这里 这篇博文说一下如何在集群基础上继续添加节点&#xff0c;也就是给集群扩容 博文中的命令出现的 111.111.111.111 均换成实际 IP 执行 创建要添加的一主一从容器 这里创建一个6377主节点和一个6378从节…

ArgoDB 5.1 正式发布:多模融合、实时分析和数据安全多重升级

Transwarp ArgoDB是星环科技自主研发的高性能分布式分析型数据库&#xff0c;在PB级数据量上提供极致的数据分析能力。ArgoDB支持标准SQL语法和分布式事务&#xff0c;提供高并发高速数据写入、复杂查询、多模分析、数据联邦、隐私计算和动态脱敏等能力。基于星环科技ArgoDB数据…

怎么自由裁剪图片大小?分享一款在线图片编辑工具

工作的时候常常需要用图片编辑工具把图片裁剪为我们想要的大小&#xff0c;但下载处理图片软件又耗费时间&#xff0c;那么有没有比较快捷的修改图片的方法呢&#xff1f;其实我们可以用在线图片处理&#xff08;在线ps 图片编辑制作工具 免费照片编辑器_压缩图&#xff09;工具…

日期插件(默认显示当前日期)---年月

方法&#xff1a;加载页面时将当前日期赋值 <!-- 选择年月--> <div class"form-group"><label class"col-sm-2 control-label is-required">时间&#xff1a;</label><button id"bin0"><< </button&g…

Nvidia 驱动安装

由于使用unreal engine editor 开发,需要安装nvidia 独显驱动,遇到各种坑,在此记录,方便自己以后再次遇到,也希望能帮助他人辟坑 系统: Ubuntu18.04 显卡:Geforce GTX 1650 UE版本:5.1.0 1. 自动安装 sudo ubuntu-drivers devices 推荐安装470 sudo ubuntu-drivers autoi…

Redis哨兵模式原理剖析,监控、选主、通知客户端你真的懂了吗?

哨兵启动后只指定了master的地址&#xff0c;要想知道整个集群中完整的拓扑关系怎么做呢&#xff1f; 哨兵每隔10秒会向每个master节点发送 info 命令&#xff0c; info 命令返回的信息中&#xff0c;包含了主从拓扑关系&#xff0c;其中包括每个slave的地址和端口号。有了这些…

[附源码]计算机毕业设计汽配管理系统Springboot程序

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

10. 获取操作系统版本和位数

1. linux如何查看系统版本 (1) 查看系统版本&#xff1a;uname -a (2) 查看内核版本信息&#xff1a;less /proc/version (3) 查看发行版本信息&#xff1a;less /etc/issue (4) 查看发行版详细信息&#xff1a;lsb_release -a 2. 怎么查看linux是32位还是64 系统 (1) getco…

Web3中文|以太坊创始人V神:关注技术,而不是价格

全球第二大数字货币交易所 FTX 轰然倒下&#xff0c;可以说是牵连甚广&#xff0c;不止是小资族&#xff0c;不少资深玩家都在这次事件中亏损数百、数千万美元。Solana、BlockFi等都在此次事件中受到巨大冲击。 基于BNB Chain的去中心化金融&#xff08;DeFi&#xff09;协议A…

Mac 上好用的远程桌面软件:Splashtop

市场分析表明&#xff0c; Mac电脑的市场份额正在增加 。在相关新闻中&#xff0c;全球远程桌面软件市场正在经历巨大的增长 。 远程桌面软件允许你通过互联网连接到一个特定的计算机&#xff0c;并用一个单独的设备来控制它。然后你就可以使用任何应用程序&#xff0c;访问主…

笔试强训48天——day23

文章目录一. 单选1.下面程序段的时间复杂度为&#xff08;&#xff09;2. 下列关于线性链表的叙述中&#xff0c;正确的是&#xff08; &#xff09;3. 下列描述的不是链表的优点是&#xff08; &#xff09;4. 向一个栈顶指针为h的带头结点的链栈中插入指针s所指的结点时,应执…

纺织进入“寒冬”,纺织企业利用APS生产排产加强生产管

进入11月&#xff0c;对于纺服产业链而言&#xff0c;大体“金九银十”的旺季订单已经结束。实际上&#xff0c;经历了前三季度的疲弱表现&#xff0c;市场整体已经对四季度缺乏信心。的确从整个下游行业来看&#xff0c;纺织出口形势依然严峻&#xff0c;预计11月份纺织行业也…