求简单表达式的值

题目:在键盘输入类似(56-20)/(4+2)这样的表达式输出结果

此题分为两部分(1)将表达式转换成后缀表达式(2)计算后缀表达式的值

需要注意的是本题要定义两个不同的栈 一个数据类型是字符,一个数据类型是double。

关于为什么这样做能算出结果读者只需稍微理解一下即可,不必深究(和递归一样)

c++代码(注释在代码里有)

(1)将表达式转换成后缀表达式

例如将(56-20)/(4+2) 转换成  56#20#-4#2#+/

#include <stdio.h>
#include <stdlib.h>
#define MaxSize 100
//---------------------------------------------------------
//--运算符栈基本运算---------------------------------------
//---------------------------------------------------------
typedef struct 
{	char data[MaxSize];			//存放运算符int top;					//栈顶指针
} SqStack;
void InitStack(SqStack *&s)		//初始化栈
{	s=(SqStack *)malloc(sizeof(SqStack));s->top=-1;
}
void DestroyStack(SqStack *&s)	//销毁栈
{free(s);
}
bool StackEmpty(SqStack *s)		//判断栈是否为空
{return(s->top==-1);
}
bool Push(SqStack *&s,char e)	//进栈元素e
{	if (s->top==MaxSize-1)return false;s->top++;s->data[s->top]=e;return true;
}
bool Pop(SqStack *&s,char &e)	//出栈元素e
{	if (s->top==-1)	return false;e=s->data[s->top];s->top--;return true;
}
bool GetTop(SqStack *s,char &e)	//取栈顶元素e
{	if (s->top==-1)	return false;e=s->data[s->top];return true;
}
//---------------------------------------------------------void trans(char *exp,char postexp[])	//将算术表达式exp转换成后缀表达式postexp
{char e;SqStack *Optr;						//定义运算符栈InitStack(Optr);					//初始化运算符栈int i=0;							//i作为postexp的下标while (*exp!='\0')					//exp表达式未扫描完时循环{	switch(*exp){case '(':						//判定为左括号Push(Optr,'(');				//左括号进栈exp++;						//继续扫描其他字符break;case ')':						//判定为右括号Pop(Optr,e);				//出栈元素ewhile (e!='(')				//不为'('时循环{postexp[i++]=e;			//将e存放到postexp中Pop(Optr,e);			//继续出栈元素e}exp++;						//继续扫描其他字符break;case '+':						//判定为加或减号case '-':while (!StackEmpty(Optr))	//栈不空循环{GetTop(Optr,e);			//取栈顶元素eif (e!='(')				//e不是'('{postexp[i++]=e;		//将e存放到postexp中Pop(Optr,e);		//出栈元素e}else					//e是'(时退出循环break;}Push(Optr,*exp);			//将'+'或'-'进栈exp++;						//继续扫描其他字符break;case '*':						//判定为'*'或'/'号case '/':while (!StackEmpty(Optr))	//栈不空循环{GetTop(Optr,e);			//取栈顶元素eif (e=='*' || e=='/')	//将栈顶'*'或'/'运算符出栈并存放到postexp中{postexp[i++]=e;		//将e存放到postexp中Pop(Optr,e);		//出栈元素e}else					//e为非'*'或'/'运算符时退出循环break;}Push(Optr,*exp);			//将'*'或'/'进栈exp++;						//继续扫描其他字符break;default:				//处理数字字符while (*exp>='0' && *exp<='9') //判定为数字{	postexp[i++]=*exp;exp++;}postexp[i++]='#';	//用#标识一个数值串结束}}while (!StackEmpty(Optr))	//此时exp扫描完毕,栈不空时循环{Pop(Optr,e);			//出栈元素epostexp[i++]=e;			//将e存放到postexp中}postexp[i]='\0';			//给postexp表达式添加结束标识DestroyStack(Optr);			//销毁栈		
}

(2)计算后缀表达式的值

typedef struct 
{	double data[MaxSize];			//存放数值int top;						//栈顶指针
} SqStack1;
void InitStack1(SqStack1 *&s)		//初始化栈
{	s=(SqStack1 *)malloc(sizeof(SqStack1));s->top=-1;
}
void DestroyStack1(SqStack1 *&s)	//销毁栈
{free(s);
}
bool StackEmpty1(SqStack1 *s)		//判断栈是否为空
{return(s->top==-1);
}
bool Push1(SqStack1 *&s,double e)	//进栈元素e
{	if (s->top==MaxSize-1)return false;s->top++;s->data[s->top]=e;return true;
}
bool Pop1(SqStack1 *&s,double &e)	//出栈元素e
{	if (s->top==-1)	return false;e=s->data[s->top];s->top--;return true;
}
bool GetTop1(SqStack1 *s,double &e)	//取栈顶元素e
{	if (s->top==-1)	return false;e=s->data[s->top];return true;
}
//---------------------------------------------------------
double compvalue(char *postexp)	//计算后缀表达式的值
{double d,a,b,c,e;SqStack1 *Opnd;				//定义操作数栈InitStack1(Opnd);			//初始化操作数栈while (*postexp!='\0')		//postexp字符串未扫描完时循环{	switch (*postexp){case '+':				//判定为'+'号Pop1(Opnd,a);		//出栈元素aPop1(Opnd,b);		//出栈元素bc=b+a;				//计算cPush1(Opnd,c);		//将计算结果c进栈break;case '-':				//判定为'-'号Pop1(Opnd,a);		//出栈元素aPop1(Opnd,b);		//出栈元素bc=b-a;				//计算cPush1(Opnd,c);		//将计算结果c进栈break;case '*':				//判定为'*'号Pop1(Opnd,a);		//出栈元素aPop1(Opnd,b);		//出栈元素bc=b*a;				//计算cPush1(Opnd,c);		//将计算结果c进栈break;case '/':				//判定为'/'号Pop1(Opnd,a);		//出栈元素aPop1(Opnd,b);		//出栈元素bif (a!=0){c=b/a;			//计算cPush1(Opnd,c);	//将计算结果c进栈break;}else{	printf("\n\t除零错误!\n");exit(0);		//异常退出}break;default:				//处理数字字符d=0;				//将连续的数字字符转换成对应的数值存放到d中while (*postexp>='0' && *postexp<='9')   //判定为数字字符{	d=10*d+*postexp-'0';  postexp++;}Push1(Opnd,d);		//将数值d进栈break;}postexp++;				//继续处理其他字符}GetTop1(Opnd,e);			//取栈顶元素eDestroyStack1(Opnd);		//销毁栈		return e;					//返回e
}

总代码:

//求简单表达式的值
#define  _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>
#define MaxSize 100
//---------------------------------------------------------
//--运算符栈基本运算---------------------------------------
//---------------------------------------------------------
typedef struct 
{	char data[MaxSize];			//存放运算符int top;					//栈顶指针
} SqStack;
void InitStack(SqStack *&s)		//初始化栈
{	s=(SqStack *)malloc(sizeof(SqStack));s->top=-1;
}
void DestroyStack(SqStack *&s)	//销毁栈
{free(s);
}
bool StackEmpty(SqStack *s)		//判断栈是否为空
{return(s->top==-1);
}
bool Push(SqStack *&s,char e)	//进栈元素e
{	if (s->top==MaxSize-1)return false;s->top++;s->data[s->top]=e;return true;
}
bool Pop(SqStack *&s,char &e)	//出栈元素e
{	if (s->top==-1)	return false;e=s->data[s->top];s->top--;return true;
}
bool GetTop(SqStack *s,char &e)	//取栈顶元素e
{	if (s->top==-1)	return false;e=s->data[s->top];return true;
}
//---------------------------------------------------------void trans(char *exp,char postexp[])	//将算术表达式exp转换成后缀表达式postexp
{char e;SqStack *Optr;						//定义运算符栈InitStack(Optr);					//初始化运算符栈int i=0;							//i作为postexp的下标while (*exp!='\0')					//exp表达式未扫描完时循环{	switch(*exp){case '(':						//判定为左括号Push(Optr,'(');				//左括号进栈exp++;						//继续扫描其他字符break;case ')':						//判定为右括号Pop(Optr,e);				//出栈元素ewhile (e!='(')				//不为'('时循环{postexp[i++]=e;			//将e存放到postexp中Pop(Optr,e);			//继续出栈元素e}exp++;						//继续扫描其他字符break;case '+':						//判定为加或减号case '-':while (!StackEmpty(Optr))	//栈不空循环{GetTop(Optr,e);			//取栈顶元素eif (e!='(')				//e不是'('{postexp[i++]=e;		//将e存放到postexp中Pop(Optr,e);		//出栈元素e}else					//e是'(时退出循环break;}Push(Optr,*exp);			//将'+'或'-'进栈exp++;						//继续扫描其他字符break;case '*':						//判定为'*'或'/'号case '/':while (!StackEmpty(Optr))	//栈不空循环{GetTop(Optr,e);			//取栈顶元素eif (e=='*' || e=='/')	//将栈顶'*'或'/'运算符出栈并存放到postexp中{postexp[i++]=e;		//将e存放到postexp中Pop(Optr,e);		//出栈元素e}else					//e为非'*'或'/'运算符时退出循环break;}Push(Optr,*exp);			//将'*'或'/'进栈exp++;						//继续扫描其他字符break;default:				//处理数字字符while (*exp>='0' && *exp<='9') //判定为数字{	postexp[i++]=*exp;exp++;}postexp[i++]='#';	//用#标识一个数值串结束}}while (!StackEmpty(Optr))	//此时exp扫描完毕,栈不空时循环{Pop(Optr,e);			//出栈元素epostexp[i++]=e;			//将e存放到postexp中}postexp[i]='\0';			//给postexp表达式添加结束标识DestroyStack(Optr);			//销毁栈		
}
//---------------------------------------------------------
//--操作数栈基本运算---------------------------------------
//---------------------------------------------------------
typedef struct 
{	double data[MaxSize];			//存放数值int top;						//栈顶指针
} SqStack1;
void InitStack1(SqStack1 *&s)		//初始化栈
{	s=(SqStack1 *)malloc(sizeof(SqStack1));s->top=-1;
}
void DestroyStack1(SqStack1 *&s)	//销毁栈
{free(s);
}
bool StackEmpty1(SqStack1 *s)		//判断栈是否为空
{return(s->top==-1);
}
bool Push1(SqStack1 *&s,double e)	//进栈元素e
{	if (s->top==MaxSize-1)return false;s->top++;s->data[s->top]=e;return true;
}
bool Pop1(SqStack1 *&s,double &e)	//出栈元素e
{	if (s->top==-1)	return false;e=s->data[s->top];s->top--;return true;
}
bool GetTop1(SqStack1 *s,double &e)	//取栈顶元素e
{	if (s->top==-1)	return false;e=s->data[s->top];return true;
}
//---------------------------------------------------------
double compvalue(char *postexp)	//计算后缀表达式的值
{double d,a,b,c,e;SqStack1 *Opnd;				//定义操作数栈InitStack1(Opnd);			//初始化操作数栈while (*postexp!='\0')		//postexp字符串未扫描完时循环{	switch (*postexp){case '+':				//判定为'+'号Pop1(Opnd,a);		//出栈元素aPop1(Opnd,b);		//出栈元素bc=b+a;				//计算cPush1(Opnd,c);		//将计算结果c进栈break;case '-':				//判定为'-'号Pop1(Opnd,a);		//出栈元素aPop1(Opnd,b);		//出栈元素bc=b-a;				//计算cPush1(Opnd,c);		//将计算结果c进栈break;case '*':				//判定为'*'号Pop1(Opnd,a);		//出栈元素aPop1(Opnd,b);		//出栈元素bc=b*a;				//计算cPush1(Opnd,c);		//将计算结果c进栈break;case '/':				//判定为'/'号Pop1(Opnd,a);		//出栈元素aPop1(Opnd,b);		//出栈元素bif (a!=0){c=b/a;			//计算cPush1(Opnd,c);	//将计算结果c进栈break;}else{	printf("\n\t除零错误!\n");exit(0);		//异常退出}break;default:				//处理数字字符d=0;				//将连续的数字字符转换成对应的数值存放到d中while (*postexp>='0' && *postexp<='9')   //判定为数字字符{	d=10*d+*postexp-'0';  postexp++;}Push1(Opnd,d);		//将数值d进栈break;}postexp++;				//继续处理其他字符}GetTop1(Opnd,e);			//取栈顶元素eDestroyStack1(Opnd);		//销毁栈		return e;					//返回e
}
int main()
{char exp[]="(56-20)/(4+2)";char postexp[MaxSize];trans(exp,postexp);printf("中缀表达式:%s\n",exp);printf("后缀表达式:%s\n",postexp);printf("表达式的值:%g\n",compvalue(postexp));return 1;
}

c语言(注释在c++里,思路是一样的故不多描述)

1)将表达式转换成后缀表达式

例如将(56-20)/(4+2) 转换成  56#20#-4#2#+/

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
typedef struct Stack
{char data[1000];int top;
}SqStack;
SqStack* InitStack()
{SqStack* s = (SqStack*)malloc(sizeof(SqStack));s->top = -1;return s;
}
bool Push(SqStack* s, char e)
{if (s->top == 1000 - 1) return false;s->top++;s->data[s->top] = e;return true;
}
bool Pop(SqStack* s, char* e)
{if (s->top == -1) return false;*e = s->data[s->top];s->top--;return true;
}
bool StackEmpty(SqStack* s)
{return (s->top == -1);
}
bool GetTop(SqStack* s, char* e)
{if (s->top == -1) return false;*e = s->data[s->top];return true;
}
void DestroyStack(SqStack* s)
{free(s);
}
void trans(char *exp,char postexp[])
{SqStack* Optr;char* e = (char*)malloc(sizeof(char));Optr = InitStack();int i = 0;while (*exp != '\0'){switch (*exp){case '(': Push(Optr, *exp); exp++; break;case ')':{Pop(Optr, e);while (*e != '('){postexp[i++] = *e;Pop(Optr, e);}exp++;break;}case '+':case '-':{while (!StackEmpty(Optr)){GetTop(Optr, e);if (*e != '('){postexp[i++] = *e;Pop(Optr, e);}else break;	}Push(Optr, *exp);exp++;break;}case '*':case '/':{while (!StackEmpty(Optr)){GetTop(Optr, e);if (*e == '*' || *e == '/'){postexp[i++] = *e;Pop(Optr, e);}else break;}Push(Optr, *exp);exp++;break;}default:{while (*exp >= '0' && *exp <= '9'){postexp[i++] = *exp;exp++;}postexp[i++] = '#';}}}while (!StackEmpty(Optr)){Pop(Optr, e);postexp[i++] = *e;}postexp[i++] = '\0';DestroyStack(Optr);
}

(2)计算后缀表达式的值

typedef struct Stk
{double data[1000];int top;
}SqStack2;
SqStack2* InitStack2()
{SqStack2* s = (SqStack2*)malloc(sizeof(SqStack2));s->top = -1;return s;
}
bool Pop2(SqStack2*s, double* e)
{if (s->top == -1) return false;*e = s->data[s->top];s->top--;return true;
}
bool Push2(SqStack2* s, double e)
{if (s->top == 1000 - 1) return false;s->top++;s->data[s->top] = e;return true;
}
bool GetTop2(SqStack2* s, double* e)
{if (s->top == -1) return false;*e = s->data[s->top];return true;
}
void DestroyStack2(SqStack2* s)
{free(s);
}
double compvalue(char postexp[])
{double a, b, c, d;double* p1 = &a, * p2 = &b, * p3 = &c;double* e = (double*)malloc(sizeof(double));SqStack2* Opnd = InitStack2();while (*postexp != '\0'){switch (*postexp){case '+':{Pop2(Opnd, p1);Pop2(Opnd, p2);*p3 = *p2 + *p1;Push2(Opnd, *p3);break;}case '-':{Pop2(Opnd, p1);Pop2(Opnd, p2);*p3 = *p2 - *p1;Push2(Opnd, *p3);break;}case '*':{Pop2(Opnd, p1);Pop2(Opnd, p2);*p3 = *p2 * (*p1);Push2(Opnd, *p3);break;}case '/':{Pop2(Opnd, p1);Pop2(Opnd, p2);if (*p1 == 0){printf("分母为零,程序错误\n");exit(0);}*p3 = *p2 / (*p1);Push2(Opnd, *p3);break;}default:{d = 0;while (*postexp >= '0' && *postexp <= '9'){d = d * 10 + (*postexp - '0');//下标和指针只用一个(一定要记住)postexp++;}Push2(Opnd, d);break;//好习惯}}postexp++;}GetTop2(Opnd, e);DestroyStack2(Opnd);return *e;
}

总代码:

#define  _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
typedef struct Stack
{char data[1000];int top;
}SqStack;
SqStack* InitStack()
{SqStack* s = (SqStack*)malloc(sizeof(SqStack));s->top = -1;return s;
}
bool Push(SqStack* s, char e)
{if (s->top == 1000 - 1) return false;s->top++;s->data[s->top] = e;return true;
}
bool Pop(SqStack* s, char* e)
{if (s->top == -1) return false;*e = s->data[s->top];s->top--;return true;
}
bool StackEmpty(SqStack* s)
{return (s->top == -1);
}
bool GetTop(SqStack* s, char* e)
{if (s->top == -1) return false;*e = s->data[s->top];return true;
}
void DestroyStack(SqStack* s)
{free(s);
}
void trans(char *exp,char postexp[])
{SqStack* Optr;char* e = (char*)malloc(sizeof(char));Optr = InitStack();int i = 0;while (*exp != '\0'){switch (*exp){case '(': Push(Optr, *exp); exp++; break;case ')':{Pop(Optr, e);while (*e != '('){postexp[i++] = *e;Pop(Optr, e);}exp++;break;}case '+':case '-':{while (!StackEmpty(Optr)){GetTop(Optr, e);if (*e != '('){postexp[i++] = *e;Pop(Optr, e);}else break;	}Push(Optr, *exp);exp++;break;}case '*':case '/':{while (!StackEmpty(Optr)){GetTop(Optr, e);if (*e == '*' || *e == '/'){postexp[i++] = *e;Pop(Optr, e);}else break;}Push(Optr, *exp);exp++;break;}default:{while (*exp >= '0' && *exp <= '9'){postexp[i++] = *exp;exp++;}postexp[i++] = '#';}}}while (!StackEmpty(Optr)){Pop(Optr, e);postexp[i++] = *e;}postexp[i++] = '\0';DestroyStack(Optr);
}
/// ///
///
//
typedef struct Stk
{double data[1000];int top;
}SqStack2;
SqStack2* InitStack2()
{SqStack2* s = (SqStack2*)malloc(sizeof(SqStack2));s->top = -1;return s;
}
bool Pop2(SqStack2*s, double* e)
{if (s->top == -1) return false;*e = s->data[s->top];s->top--;return true;
}
bool Push2(SqStack2* s, double e)
{if (s->top == 1000 - 1) return false;s->top++;s->data[s->top] = e;return true;
}
bool GetTop2(SqStack2* s, double* e)
{if (s->top == -1) return false;*e = s->data[s->top];return true;
}
void DestroyStack2(SqStack2* s)
{free(s);
}
double compvalue(char postexp[])
{double a, b, c, d;double* p1 = &a, * p2 = &b, * p3 = &c;double* e = (double*)malloc(sizeof(double));SqStack2* Opnd = InitStack2();while (*postexp != '\0'){switch (*postexp){case '+':{Pop2(Opnd, p1);Pop2(Opnd, p2);*p3 = *p2 + *p1;Push2(Opnd, *p3);break;}case '-':{Pop2(Opnd, p1);Pop2(Opnd, p2);*p3 = *p2 - *p1;Push2(Opnd, *p3);break;}case '*':{Pop2(Opnd, p1);Pop2(Opnd, p2);*p3 = *p2 * (*p1);Push2(Opnd, *p3);break;}case '/':{Pop2(Opnd, p1);Pop2(Opnd, p2);if (*p1 == 0){printf("分母为零,程序错误\n");exit(0);}*p3 = *p2 / (*p1);Push2(Opnd, *p3);break;}default:{d = 0;while (*postexp >= '0' && *postexp <= '9'){d = d * 10 + (*postexp - '0');//下标和指针只用一个(一定要记住)postexp++;}Push2(Opnd, d);break;//好习惯}}postexp++;}GetTop2(Opnd, e);DestroyStack2(Opnd);return *e;
}
int main()
{char exp[100] = "(56-20)/(4+2)";char postexp[100];printf("初始表达式:%s\n", exp);trans(exp, postexp);printf("后缀表达式:%s\n", postexp);printf("表达式的值为:%.2lf\n", compvalue(postexp));return 0;
}

总结:

利用栈的特性巧妙的解决(大家一定要自己动手实践一下),代码看起来很长其实很多都是栈的基本运算。(看到这里点个赞👍呗,辛苦啦)

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

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

相关文章

Spring Boot:Spring Boot 入门、yaml 配置文件给属性赋值、自动装配原理详解

文章目录 Spring Boot - 01一、概述二、第一个 Spring Boot 程序补充知识 三、配置文件1. yaml 配置文件2. 使用 yaml 配置文件给属性赋值3. 松散绑定以及数据校验4. 配置文件的位置以及多环境配置 四、Spring Boot 分析1. pom.xml2. 启动器3. 主程序4. 自动装配原理5. 主启动类…

数栈UI5.0设计实战|B端表单这样设计,不仅美观还提效

表单是B端产品中最常见的组件之一&#xff0c;主要⽤于数据收集、校验和提交。比如登陆流程的账号密码填写&#xff0c;注册流程的邮箱、用户名等信息填写&#xff0c;都是表单应用的常见案例&#xff0c;在数栈产品中也是出现频率⾮常⾼的组件。 尽管表单应用十分普遍&#x…

腾讯云4核8G服务器轻量和CVM标准型S5对比

腾讯云4核8G服务器优惠价格表&#xff0c;云服务器CVM标准型S5实例4核8G配置价格15个月1437.3元&#xff0c;5年6490.44元&#xff0c;轻量应用服务器4核8G12M带宽一年446元、529元15个月&#xff0c;阿腾云atengyun.com分享腾讯云4核8G服务器详细配置、优惠价格及限制条件&…

网络通信协议

WebSocket通信 WebSocket是一种基于TCP的网络通信协议&#xff0c;提供了浏览器和服务器之间的全双工通信&#xff08;full-duplex&#xff09;能力。在WebSocket API中&#xff0c;浏览器和服务器只需要完成一次握手&#xff0c;两者之间就直接可以创建持久性的连接&#xff…

虚幻学习笔记16—C++和3DUI(二)

一、前言 上一篇虚幻学习笔记15—C和UI&#xff08;一&#xff09;中介绍了通过C代码创建2D的ui&#xff0c;本章主要讲解怎么用C代码创建3D的UI&#xff0c;在虚幻学习笔记3—UI跟随弹窗这章中讲解了怎样用蓝图创建一个3D的UI&#xff0c;并且和其交互。 本系列使用的虚幻5.2.…

【Tensor张量】AI模型的信息流通货币

官方解释https://www.tensorflow.org/guide/tensor?hl=zh-cn 1.Tensor的概念理解 如果大模型是一个会运行的城市工厂,那么Tensor就是 运输车! 如果大模型是计算机,那么Tensor就是硬盘。 负责深度学习数据的运输和存储!把数据送给AI模型进行训练,AI模型推理后的数据也…

操作系统“文艺复兴”,云数智融合涌现“美第奇效应”

操作系统作为信息技术中的基础软件&#xff0c;是现代计算机的“灵魂”。随着大模型AI推动云计算、大数据、人工智能、物联网和5G等新一代数字技术的飞速融合&#xff0c;现代计算机体系结构和软件架构面临着重大创新机遇期。图灵奖获得者John Hennessy和David Patterson早在20…

接口测试学习笔记

文章目录 认识urlhttp协议接口规范Postman实现接口测试设计接口测试用例使用软件发送请求并查看响应结果Postman 自动关联Postman如何提交multipart/form-data请求数据Postman如何提交查询参数Postman 如何批量执行用例单接口测试Postman 断言Postman参数化 接口测试自动化requ…

家有一宝,快乐翻倍,最新最全面基于AdGuard Home 自建 DNS 防污染、去广告教程、安装部署详解、优化增强设置详解

家有一宝,快乐翻倍,最新最全面基于AdGuard Home 自建 DNS 防污染、去广告教程、安装部署详解、优化增强设置详解。支持各个客户端,全平台覆盖。 AdGuard Home 部署的方式有很多种,一般二进制文件部署和直接编译到 OpenWrt 系统中是大家所常用的。而博主个人倾向于使用 Dock…

Qt/C++控件设计器/属性栏/组态/可导入导出/中文属性/串口网络/拖曳开发

一、功能特点 自动加载插件文件中的所有控件生成列表&#xff0c;默认自带的控件超过120个。拖曳到画布自动生成对应的控件&#xff0c;所见即所得。右侧中文属性栏&#xff0c;改变对应的属性立即应用到对应选中控件&#xff0c;直观简洁&#xff0c;非常适合小白使用。独创属…

CTF特训(一):ctfshow-RCE挑战

CTF特训(一)&#xff1a;ctfshow-RCE挑战 FLAG&#xff1a;可后来&#xff0c;除了梦以外的地方&#xff0c;我再也没有见过你 专研方向: 代码审计&#xff0c;PHP 每日emo&#xff1a;其实挺迷茫的&#xff0c;不知道该干什么,(骗你的) RCE挑战1 <?phperror_reporting(0)…

数据密钥管理有哪些常见技术

数据密钥管理涉及到许多复杂而重要的技术&#xff0c;以下是一些常见的数据密钥管理技术&#xff1a; 密钥生成技术&#xff1a;这是数据密钥管理的第一步&#xff0c;需要生成安全、随机且唯一的密钥。常见的密钥生成算法包括RSA、ECC(椭圆曲线密码学)等。这些算法能够生成长度…

EternalBlue【永恒之蓝】漏洞详解(复现、演示、远程、后门、入侵、防御)内容丰富-深入剖析漏洞原理-漏洞成因-以及报错解决方法-值得收藏!

漏洞背景&#xff1a; 1.何为永恒之蓝&#xff1f; 永恒之蓝&#xff08;Eternal Blue&#xff09;爆发于2017年4月14日晚&#xff0c;是一种利用Windows系统的SMB协议漏洞来获取系统的最高权限&#xff0c;以此来控制被入侵的计算机。甚至于2017年5月12日&#xff0c; 不法分子…

2015年第四届数学建模国际赛小美赛B题南极洲的平均温度解题全过程文档及程序

2015年第四届数学建模国际赛小美赛 B题 南极洲的平均温度 原题再现&#xff1a; 地表平均温度是反映气候变化和全球变暖的重要指标。然而&#xff0c;在以前的估计中&#xff0c;在如何界定土地平均数方面存在一些方法上的差异。为简单起见&#xff0c;我们只考虑南极洲。请建…

mysql-exporter监控部署(k8s内)tensuns专用

一、前言 在k8s内部署mysql-exporter监控需要用到deployment、service服务 二、部署 在被监控的mysql中创建监控用户 mysql -u root -p GRANT PROCESS, REPLICATION CLIENT ON *.* TO monitor% identified by 12345678; flush privileges; 创建mysql-exporter服务的yaml文件存…

微信小程序预览pdf,修改pdf文件名

记录微信小程序预览pdf文件&#xff0c;修改pdf名字安卓和ios都可用。 1.安卓和苹果的效果 2.需要用到的api 1.wx.downloadFile wx.downloadFile 下载文件资源到本地。客户端直接发起一个 HTTPS GET 请求&#xff0c;返回文件的本地临时路径 (本地路径)&#xff0c;单次下载…

振弦采集仪在地铁隧道施工监测中的应用与分析

振弦采集仪在地铁隧道施工监测中的应用与分析 振弦采集仪是一种常用的地铁隧道施工监测工具&#xff0c;它通过测量隧道结构中的振弦变化来判断隧道施工的稳定性和安全性。振弦采集仪的应用与分析可以帮助工程师监测地铁隧道施工过程中的变化&#xff0c;及时发现可能的问题并…

test-03-java 单元测试框架 testNG 入门介绍 junit/junit5/testNG 详细对比

拓展阅读 test-01-java 单元测试框架 junit 入门介绍 test-02-java 单元测试框架 junit5 入门介绍 test-03-java 单元测试框架 testNG 入门介绍 junit/junit5/testNG 详细对比 test assert-01-Google Truth 断言 test 系统学习-03-TestNG Spock testng 入门使用教程 开源…

探索 WebRTC:数字世界的实时通信魔法

前言 在当今日常生活中&#xff0c;我们期望能够随时随地与朋友、同事或家人进行实时沟通。WebRTC&#xff08;Web实时通信&#xff09;技术就像一种魔法&#xff0c;让这些交流变得无比便捷&#xff0c;而且完全在浏览器中实现&#xff0c;无需下载任何额外应用或插件。 Web…

对接日志服务器系统,将业务服务器、数据库服务器等系统日志rsyslog统一推送或接入至日志服务器进行检测及日志的抓取分析。

1、客户端业务系统服务器配置&#xff0c;系统日志配置文件默认存放在/etc/rsyslog.conf下&#xff1b; 2、打开系统日志推送配置&#xff08;其它邮件日志、开机日志、消息日志等都可统一接入&#xff09; 3、配置推送地址和协议 这里特别说明一下&#xff1a;【注意&#xff…