C#利用栈实现加减乘除运算
作者:Don_Yao 发布时间:2021-09-16 06:56:19
还是有一些小问题....懒得改了,但大体思路还是清晰的,首先定义一个运算符栈,一个数栈。
关于优先级,两个括号(,)优先级最低,其次是+、-,最高的是*、/
关于运算法则,打个比方,"(3+5*4)+3"这个串
首先遇到左括号,直接压入运算符栈,然后是3,直接压入数栈,然后遇到5,压入数栈,遇到*,将其压入运算符栈,遇到右括号,将运算符栈顶的*取出,取出两个数栈栈顶的数,进行乘法运算,将运算结果压入数栈,因为此时运算符栈顶仍不是左括号,取出栈顶的+号,拿出数栈栈顶的两个数,进行加法运算,并将结果压入数栈。此时栈顶是左括号了,那么将左括号弹出栈。此时数栈里还有一个23,运算符栈为空。接着来。此时轮到了+号,直接压入数栈,遇到3,直接压入数栈。此时发现串已经结尾了,但是运算符栈还没有清空。那么就清空吧,把+号拿出来,数栈的23和3拿出来,加法运算,结果压入数栈。此时运算符栈清空,数栈剩个26。这就是最后的结果。是不是很简单但是有一点云里雾里。。
说一下运算规则吧。优先级大家都知道了,优先级从高到低依次是 "*/","+-","()",每当要压运算符时,首先得看看运算符栈里有什么,如果没有,肯定是可以直接压入的,左括号也是可以不管三七二十一直接压入的,除此之外,如果遇到栈顶运算符优先级更高时,是必须将栈顶运算符先取出来运算,直到栈顶元素优先级小于或者等于要压入的运算符的优先级才可压入。比如3*5+5+5,在压入第一个+号时,必须先将栈里的*号先拿出来运算结束后,才能放进去,否则计算结果将是错误的。当压入的是右括号时,必须一直弹运算符栈进行运算,直到遇到左括号为止。当串扫描到末尾时,也必须将运算符栈清空,最后留在数栈的数就是结果。关于小数点,关于复数加减运算,我写的小程序里有了一定的处理
就类似于这样的简单功能。。。。恩,将就看看吧。。程序不完善,不过也懒得改了,毕竟是练习,最近事又多。
下面贴一下源码
主要用到的几个类和方法:
类Parser 的parse方法,比如给一个“3+4i”的字符串,返回给你一个3个结点的队,队列第一个元素是一个ComplexNumber对象,实数域为3,队列的第二个元素是“+”号,队列第三个元素是一个ComplexNumber对象,实数域为0,虚数域为4。
类Operators 用于测试字符是否是运算符,用来进行控制运算,比较运算符优先级....
类Handler 给一个字符串,他帮你处理,返回给你一个结果。其实就是调一下Parser类的方法去解析一下字符串,然后算一下结果,然后返回结果。
类ComplexNumber,就是复数类啊,不用说了,提供实数域虚数域,getset方法,加减乘除以及toString()方法
using System;
using System.Collections;
using System.Text;
namespace MySpace{
class Parser{
public static Queue Parse(string input){
char[] arr = input.ToCharArray();
Queue queue = new Queue();
foreach(char x in arr){
queue.Enqueue(x);
}
queue = ParseStringQueue(queue);
return queue;
}
//传入字符串队列,返回封装好的队列。
//ComplexNumber对象或char类型运算符各占用一个结点
private static Queue ParseStringQueue(Queue queue){
Queue secondQ = new Queue();
char c;
StringBuilder sb = null;
string temp;
int count = queue.Count;
bool flag = false; //false表示允许创建新SB对象进行缓存数字字符串
for(int i=0;i<count;i++){
c = (char)queue.Dequeue();
if(!Operators.Contains(c)){
//如果扫描到的不是运算符,则将其加入到buffer尾部
if(!flag){
flag = true;
sb = new StringBuilder();
}
sb.Append(c);
}
if(Operators.Contains(c) || queue.Count == 0){
//如果扫描到的是运算符,则将缓冲区中的串加入队尾
if(sb != null && flag == true){
temp = sb.ToString();
try{
if(temp.EndsWith("i")){
if(temp.Length==1){
secondQ.Enqueue(new ComplexNumber(0,1));
}else{
//i前有数字则开出数字部分。
temp = temp.Substring(0,temp.Length-1);
secondQ.Enqueue(new ComplexNumber(0,double.Parse(temp)));
}
}else{
secondQ.Enqueue(new ComplexNumber(double.Parse(temp),0));
}
sb = null;
flag = false;
}catch(Exception e){
Console.WriteLine("Error");
}
}
//如果是运算符,则最后将运算符放入队。
if(Operators.Contains(c)){
secondQ.Enqueue(c);
}
}
}
return secondQ;
}
}
class ComplexNumber{
private double m_dRealPart;
private double m_dImaginPart;
public ComplexNumber(){
m_dRealPart = 0.0;
m_dImaginPart = 0.0;
}
public ComplexNumber(double r,double i){
m_dRealPart = r;
m_dImaginPart = i;
}
public ComplexNumber(ComplexNumber c){
m_dRealPart = c.GetRealPart();
m_dImaginPart = c.GetImaginaryPart();
}
//get,set方法
public double GetRealPart(){
return m_dRealPart;
}
public double GetImaginaryPart(){
return m_dImaginPart;
}
public void SetRealPart(double d){
m_dRealPart = d;
}
public void SetImaginaryPart(double d){
m_dImaginPart = d;
}
public ComplexNumber ComplexAdd(ComplexNumber c){
return new ComplexNumber(this.m_dRealPart + c.GetRealPart(),this.m_dImaginPart + c.GetImaginaryPart());
}
public ComplexNumber ComplexAdd(double c){
return new ComplexNumber(
this.m_dRealPart + c,
this.m_dImaginPart);
}
public ComplexNumber ComplexMinus(ComplexNumber c){
return new ComplexNumber(this.m_dRealPart - c.GetRealPart(),this.m_dImaginPart - c.GetImaginaryPart());
}
public ComplexNumber ComplexMinus(double c){
return new ComplexNumber(this.m_dRealPart - c, this.m_dImaginPart);
}
//乘
public ComplexNumber ComplexMulti(ComplexNumber c){
return new ComplexNumber(
this.m_dRealPart * c.GetRealPart()
- this.m_dImaginPart * c.GetImaginaryPart(),
this.m_dRealPart *
c.GetImaginaryPart()
+ this.m_dImaginPart *
c.GetRealPart());
}
public ComplexNumber ComplexMulti(double c){
return
new ComplexNumber(
this.m_dRealPart * c,
this.m_dImaginPart * c);
}
//除
public ComplexNumber ComplexDivision(ComplexNumber c){
return
new ComplexNumber((this.m_dRealPart*c.GetRealPart()
+this.m_dImaginPart*c.GetImaginaryPart())/(c.GetRealPart()*c.GetRealPart()+c.GetImaginaryPart()*c.GetImaginaryPart())
,(this.m_dImaginPart*c.GetRealPart()-this.m_dRealPart*c.GetImaginaryPart())
/(c.GetRealPart()*c.GetRealPart()+c.GetImaginaryPart()*c.GetImaginaryPart()));
}
public ComplexNumber ComplexDivision(double c){
return new
ComplexNumber(this.m_dRealPart/c,this.m_dImaginPart/c);
}
public override String ToString(){
return "(" + m_dRealPart + " + " + m_dImaginPart + " i" + ")";
}
}
class Operators{
static char[][] signOperator;
static Operators(){
signOperator = new char[3][];
signOperator[0] = new char[2];
signOperator[0][0]='*';
signOperator[0][1]='/';
signOperator[1] = new char[2];
signOperator[1][0]='+';
signOperator[1][1]='-';
signOperator[2] = new char[2];
signOperator[2][0]='(';
signOperator[2][1]=')';
}
public static int ComparePriority(char firstSign,char secondSign){
int priorityF = 0,priorityS = 0;
for(int i = 0; i<signOperator.Length;i++){
foreach(char x in signOperator[i]){
if(firstSign == x){
priorityF = i;
}
if(secondSign == x){
priorityS = i;
}
}
}
return (priorityF-priorityS);
}
public static bool Contains(char x){
foreach(char[] arr in signOperator){
foreach(char y in arr){
if(x == y){
return true;
}
}
}
return false;
}
public static ComplexNumber Compute(char ope,ComplexNumber c1,ComplexNumber c2){
ComplexNumber result = null;
switch(ope){
case '+':result=c1.ComplexAdd(c2);break;
case '-':result=c2.ComplexMinus(c1);break;
case '*':result=c1.ComplexMulti(c2);break;
case '/':result=c1.ComplexDivision(c2);break;
}
return result;
}
}
class Handler{
private Stack complexNumberStack = new Stack();
private Stack operatorStack = new Stack();
private static Handler handler = new Handler();
private Handler(){}
public static Handler GetHandler(){
return handler;
}
public ComplexNumber Process(string inputString){
Queue queue = Parser.Parse(inputString);
ComplexNumber complexNumber = null;
char c,top,ct;
int count = queue.Count;
for(int i=0;i<count;i++){
Object obj = queue.Dequeue();
if(obj is char){
c = (char)obj;
if(operatorStack.Count == 0){
operatorStack.Push(c);
}else{
top = (char)operatorStack.Peek();
if(c=='('){
operatorStack.Push(c); //左括号直接压入。不判断栈顶
}else if(c==')'){
//右括号压入前观察栈顶,若栈顶是左括号,则弹出栈顶的左括号
//否则弹出栈顶运算符,从数栈中弹出操作数进行运算,并将结果重新压入数栈,直到遇到左括号
while((ct=(char)operatorStack.Pop())!='('){
ComplexNumber c1 = (ComplexNumber)complexNumberStack.Pop();
ComplexNumber c2 = (ComplexNumber)complexNumberStack.Pop();
ComplexNumber c3 = Operators.Compute(ct,c1,c2);
complexNumberStack.Push(c3);
}
}else if(Operators.ComparePriority(top,c)<0){
//若即将压入的运算符不是括号,则比较栈顶运算符和即将压入的运算符的优先级
//如果栈顶优先级高,则将栈顶运算符取出运算,直到栈顶优先级不大于其。
while(Operators.ComparePriority((char)operatorStack.Peek(),c)<0){
ComplexNumber c1 = (ComplexNumber)complexNumberStack.Pop();
ComplexNumber c2 = (ComplexNumber)complexNumberStack.Pop();
ComplexNumber c3 = Operators.Compute((char)operatorStack.Pop(),c1,c2);
complexNumberStack.Push(c3);
operatorStack.Push(c);
}
}else{
operatorStack.Push(c);
}
}
}else if(obj is ComplexNumber) {
complexNumber = (ComplexNumber)obj;
complexNumberStack.Push(complexNumber);
}
if(queue.Count == 0){
if(operatorStack.Count != 0){
while(operatorStack.Count != 0){
c = (char)operatorStack.Pop();
ComplexNumber c1 = (ComplexNumber)complexNumberStack.Pop();
ComplexNumber c2 = (ComplexNumber)complexNumberStack.Pop();
ComplexNumber c3 = Operators.Compute(c,c1,c2);
complexNumberStack.Push(c3);
}
}
}
}
return (ComplexNumber)complexNumberStack.Pop();
}
}
class PrimeClass{
static void Main(string[] args){
String input;
Handler handler = Handler.GetHandler();
while(!(input = Console.ReadLine()).Equals("END")){
ComplexNumber c = (ComplexNumber)handler.Process(input);
Console.WriteLine(c);
};
}
}
}
Don_Yao整合修复一些bug后的代码
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
// 解析计算字符串公式
namespace CalcuStrFormula
{
// 处理类
class Handler
{
private Stack _complexNumberStack = new Stack();
private Stack _operatorStack = new Stack();
private Parser _parser = new Parser();
private Operators _operators = new Operators();
private static Handler _instance;
public static Handler instance
{
get
{
if (_instance == null)
{
_instance = new Handler();
}
return _instance;
}
}
public ComplexNumber Process(string inputString)
{
_complexNumberStack.Clear();
_operatorStack.Clear();
Queue<object> queue = _parser.Parse(inputString);
ComplexNumber complexNumber = null;
char op, topOp;
int count = queue.Count;
for (int i = 0; i < count; i++)
{
object obj = queue.Dequeue();
if (obj is char)
{
op = (char)obj;
if (_operatorStack.Count == 0)
{
_operatorStack.Push(op);
}
else
{
topOp = (char)_operatorStack.Peek();
if (op == '(')
{
_operatorStack.Push(op); // 左括号直接压入。不判断栈顶
}
else if (op == ')')
{
// 右括号压入前观察栈顶,若栈顶是左括号,则弹出栈顶的左括号
// 否则弹出栈顶运算符,从数栈中弹出操作数进行运算,并将结果重新压入数栈,直到遇到左括号
while ((topOp = (char)_operatorStack.Pop()) != '(')
{
ComplexNumber c1 = (ComplexNumber)_complexNumberStack.Pop(); // 符号右边数
ComplexNumber c2 = null; // 符号左边数
if (_operators.IsTwoNumOperator(topOp))
{
c2 = (ComplexNumber)_complexNumberStack.Pop();
}
ComplexNumber c3 = _operators.Compute(topOp, c2, c1);
_complexNumberStack.Push(c3);
}
}
else if (_operators.ComparePriority(topOp, op) <= 0)
{
// 若即将压入的运算符不是括号,则比较栈顶运算符和即将压入的运算符的优先级
// 如果栈顶优先级高,则将栈顶运算符取出运算,直到栈顶优先级不大于其。
while (_operatorStack.Count != 0 && _operators.ComparePriority((char)_operatorStack.Peek(), op) <= 0)
{
topOp = (char)_operatorStack.Pop();
ComplexNumber c1 = (ComplexNumber)_complexNumberStack.Pop(); // 符号右边数
ComplexNumber c2 = null; // 符号左边数
if (_operators.IsTwoNumOperator(topOp))
{
c2 = (ComplexNumber)_complexNumberStack.Pop();
}
ComplexNumber c3 = _operators.Compute(topOp, c2, c1);
_complexNumberStack.Push(c3);
}
_operatorStack.Push(op);
}
else
{
_operatorStack.Push(op);
}
}
}
else if (obj is ComplexNumber)
{
complexNumber = (ComplexNumber)obj;
_complexNumberStack.Push(complexNumber);
}
if (queue.Count == 0)
{
while (_operatorStack.Count != 0)
{
topOp = (char)_operatorStack.Pop();
ComplexNumber c1 = (ComplexNumber)_complexNumberStack.Pop(); // 符号右边数
ComplexNumber c2 = null; // 符号左边数
if (_operators.IsTwoNumOperator(topOp))
{
c2 = (ComplexNumber)_complexNumberStack.Pop();
}
ComplexNumber c3 = _operators.Compute(topOp, c2, c1);
_complexNumberStack.Push(c3);
}
}
}
return (ComplexNumber)_complexNumberStack.Pop();
}
}
// 3+4i解析成Queue包含 3, +, 4i
public class Parser
{
private Operators _operators = new Operators();
public Queue<object> Parse(string input)
{
input = input.Replace(" ", "");
if (input.StartsWith("-")) input = '0' + input;
char[] arr = input.ToCharArray();
Queue<char> queueChar = new Queue<char>();
foreach (char x in arr)
{
queueChar.Enqueue(x);
}
Queue<object> queueResult = ParseStringQueue(queueChar);
return queueResult;
}
// 传入字符串队列,返回封装好的队列。
// ComplexNumber对象或char类型运算符各占用一个结点
private Queue<object> ParseStringQueue(Queue<char> queue)
{
Queue<object> secondQ = new Queue<object>();
char c;
StringBuilder sb = null;
string temp;
int count = queue.Count;
bool flag = false; // false表示允许创建新SB对象进行缓存数字字符串
for (int i = 0; i < count; i++)
{
c = queue.Dequeue();
if (!_operators.Contains(c))
{
// 如果扫描到的不是运算符,则将其加入到buffer尾部
if (!flag)
{
flag = true;
sb = new StringBuilder();
}
sb.Append(c);
}
if (_operators.Contains(c) || queue.Count == 0)
{
// 如果扫描到的是运算符,则将缓冲区中的串加入队尾
if (sb != null && flag == true)
{
temp = sb.ToString();
try
{
if (temp.EndsWith("i"))
{
if (temp.Length == 1)
{
secondQ.Enqueue(new ComplexNumber(0, 1));
}
else
{
// i前有数字则开出数字部分。
temp = temp.Substring(0, temp.Length - 1);
secondQ.Enqueue(new ComplexNumber(0, double.Parse(temp)));
}
}
else
{
secondQ.Enqueue(new ComplexNumber(double.Parse(temp), 0));
}
sb = null;
flag = false;
}
catch (Exception e)
{
UnityEngine.Debug.Log("Error " + e.ToString());
}
}
// 如果是运算符,则最后将运算符放入队。
if (_operators.Contains(c))
{
secondQ.Enqueue(c);
}
}
}
return secondQ;
}
}
// 复数类,提供实数域虚数域,getset方法,加减乘除以及toString()方法
class ComplexNumber
{
private double _realPart; // 实数部分
private double _imaginPart; // 虚数部分
public ComplexNumber()
{
_realPart = 0.0;
_imaginPart = 0.0;
}
public ComplexNumber(double r, double i)
{
_realPart = r;
_imaginPart = i;
}
public ComplexNumber(ComplexNumber c)
{
_realPart = c.GetRealPart();
_imaginPart = c.GetImaginaryPart();
}
// get,set方法
public double GetRealPart()
{
return _realPart;
}
public double GetImaginaryPart()
{
return _imaginPart;
}
public void SetRealPart(double d)
{
_realPart = d;
}
public void SetImaginaryPart(double d)
{
_imaginPart = d;
}
// 加
public ComplexNumber ComplexAdd(ComplexNumber c)
{
return new ComplexNumber(_realPart + c.GetRealPart(), _imaginPart + c.GetImaginaryPart());
}
public ComplexNumber ComplexAdd(double c)
{
return new ComplexNumber(_realPart + c, _imaginPart);
}
// 减
public ComplexNumber ComplexMinus(ComplexNumber c)
{
return new ComplexNumber(_realPart - c.GetRealPart(), _imaginPart - c.GetImaginaryPart());
}
public ComplexNumber ComplexMinus(double c)
{
return new ComplexNumber(_realPart - c, _imaginPart);
}
// 乘
public ComplexNumber ComplexMulti(ComplexNumber c)
{
return new ComplexNumber(
_realPart * c.GetRealPart()
- _imaginPart * c.GetImaginaryPart(),
_realPart *
c.GetImaginaryPart()
+ _imaginPart *
c.GetRealPart());
}
public ComplexNumber ComplexMulti(double c)
{
return new ComplexNumber(_realPart * c, _imaginPart * c);
}
// 除
public ComplexNumber ComplexDivision(ComplexNumber c)
{
return new ComplexNumber((_realPart * c.GetRealPart() + _imaginPart * c.GetImaginaryPart())
/ (c.GetRealPart() * c.GetRealPart() + c.GetImaginaryPart() * c.GetImaginaryPart())
, (_imaginPart * c.GetRealPart() - _realPart * c.GetImaginaryPart())
/ (c.GetRealPart() * c.GetRealPart() + c.GetImaginaryPart() * c.GetImaginaryPart()));
}
public ComplexNumber ComplexDivision(double c)
{
return new ComplexNumber(_realPart / c, _imaginPart / c);
}
// 幂
public ComplexNumber ComplexPow(ComplexNumber c)
{
int pow;
if (int.TryParse(c.GetRealPart().ToString(), out pow))
{
ComplexNumber origin = new ComplexNumber(this);
ComplexNumber multi = new ComplexNumber(this);
for (int i = 0; i < pow - 1; i++)
{
origin = origin.ComplexMulti(multi);
}
return origin;
}
else
{
return ComplexPow(c.GetRealPart());
}
}
public ComplexNumber ComplexPow(double c)
{
return new ComplexNumber(Math.Pow(_realPart, c), 0.0);
}
// 最小值
public ComplexNumber ComplexMinimum(ComplexNumber c)
{
if (_realPart <= c.GetRealPart()) return this;
return c;
}
// 最大值
public ComplexNumber ComplexMaximum(ComplexNumber c)
{
if (_realPart >= c.GetRealPart()) return this;
return c;
}
// 转int
public ComplexNumber ToFloorInt()
{
_realPart = Math.Floor(_realPart);
return this;
}
public override string ToString()
{
return "(" + _realPart + " + " + _imaginPart + " i" + ")";
}
}
// 操作符类
class Operators
{
private char[][] _signOperator;
public Operators()
{
// 从上到下,优先级由高到低
_signOperator = new char[4][];
_signOperator[0] = new char[4];
_signOperator[0][0] = '^';
_signOperator[0][1] = 's'; // 最小值
_signOperator[0][2] = 'b'; // 最大值
_signOperator[0][3] = 'i'; // int值
_signOperator[1] = new char[2];
_signOperator[1][0] = '*';
_signOperator[1][1] = '/';
_signOperator[2] = new char[2];
_signOperator[2][0] = '+';
_signOperator[2][1] = '-';
_signOperator[3] = new char[2];
_signOperator[3][0] = '(';
_signOperator[3][1] = ')';
}
// 比较操作符优先级
public int ComparePriority(char firstSign, char secondSign)
{
int priorityF = 0, priorityS = 0;
for (int i = 0; i < _signOperator.Length; i++)
{
foreach (char x in _signOperator[i])
{
if (firstSign == x)
{
priorityF = i;
}
if (secondSign == x)
{
priorityS = i;
}
}
}
return (priorityF - priorityS);
}
// 是否是需要两个参数的操作符
public bool IsTwoNumOperator(char op)
{
if (op == 'i') return false;
return true;
}
public bool Contains(char x)
{
if (x == '(' || x == ')')
{
UnityEngine.Debug.LogError(x + "为中文字符,请改为英文字符");
}
foreach (char[] arr in _signOperator)
{
foreach (char y in arr)
{
if (x == y)
{
return true;
}
}
}
return false;
}
public ComplexNumber Compute(char op, ComplexNumber c1, ComplexNumber c2)
{
ComplexNumber result = null;
switch (op)
{
case '+': result = c1.ComplexAdd(c2); break;
case '-': result = c1.ComplexMinus(c2); break;
case '*': result = c1.ComplexMulti(c2); break;
case '/': result = c1.ComplexDivision(c2); break;
case '^': result = c1.ComplexPow(c2); break;
case 's': result = c1.ComplexMinimum(c2); break;
case 'b': result = c1.ComplexMaximum(c2); break;
case 'i': result = c2.ToFloorInt(); break;
}
return result;
}
}
}
来源:https://www.cnblogs.com/DonYao/p/11539980.html


猜你喜欢
- 尝试了各种防止中文乱码的方式,但是还是乱码;最后还是细节问题导致;解决方式:以及俩种方式是百度的,我的问题不是这俩块1.在requestMa
- 这篇文章主要介绍了Java获取时间打印到控制台代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋
- 废话不多说了,直接步入正题了。1、批量添加元素session.insert(String string,Object o)public vo
- 近期由于负责项目的一个模块,该模块下有很多分类,每个分类都有一个编码code,这个值是作为一个参数携带过来的。但是每个code确实对应一个方
- spring boot RestTemplate 发送get请求踩坑闲话少说,代码说话RestTemplate 实例手动实例化,这个我基本不
- 这篇实例中有四个类,分别为CacheItem 缓存实体类CachePool 缓存池Student 学生实
- Command模式是最让我疑惑的一个模式,我在阅读了很多代码后,才感觉隐约掌握其大概原理,我认为理解设计模式最主要是掌握起原理构造,这样才对
- 有了Eureka服务注册发现、Hystrix断路器、Ribbon服务调用负载均衡,以及spring cloud config 集群配置中心,
- Maven的安装安装Maven之前要确保已经安装好了jdk,并且配置好了环境变量JAVA_HOME。具体安装步骤如下:1. 从ap
- 发现公司集成apollo后原来的@value注入的属性不用做任何变动,也没有换成apollo的注解,遂略看源码后大致了解,做此笔记1、根据文
- 前言公众号上有网友询问我如何生成 EMF 文件的问题:本以为非常简单,我快速给出了解决方案:var bitmap = new Bitmap(
- 前言日常开发中,特别是音视频开发,需要在界面上渲染视频,比如制作一个播放器、或者视频编辑工具、以及视频会议客户端。通常拿到的是像素格式数据,
- Android ListView的优化,在做Android项目的时候,在用到ListView 界面及数据显示,这个时候如果资源过大,对项目来
- 目录一、handler基本认识1、基本组成2、基本使用方法3、工作流程二、发送消息三、消息进入消息队列1、入队前的准备工作2、将消息加入队列
- 原则:1、函数指针,实际上是函数编码后的指令在内存中的首地址,在C++/C中,这个地址可以用函数名直接使用一个函数调用另一个函数的时候,就可
- 通过ssh实现服务器文件上传下载写在前面的话之前记录过一篇使用apache的FTP开源组件实现服务器文件上传下载的方法,但是后来发现在删除的
- 实现步骤step1:添加乐观锁 * MP的其他 * 功能可以参考官网@Beanpublic MybatisPlusInterceptor m
- 前言反射和注解在java中偏高级用法,一般在各种框架中被广泛应用,文章简单介绍下反射和注解的用法,希望对你的工作学习有一定帮助java注解什
- logback输出日志屏蔽quartz的debug等级日志在一个spring的老项目中,使用了logback来作为日志管理,logback.
- 一、登录认证基于过滤器链Spring Security的登录验证流程核心就是过滤器链。当一个请求到达时按照过滤器链的顺序依次进行处理,通过所