编写代码时,有时会遇到需要分析四种算术表达式的情况。本文简要介绍了用javascript分析简单的四种算术表达式。

首先,熟悉这个概念

中缀表示法(或中缀表示法)是一种常见的算术或逻辑公式表示,运营商在中缀形式操作数中(例如:3 + 4)。我们最常用的算术表达式中缀表达式,人类更容易理解,但不容易的计算机分析。

逆波兰表示法(逆波兰式RPN,或逆波兰记法),是一个波兰数学家Jan ukasiewicz通过数学表达式1920介绍,波兰反符号,所有操作员在操作数,它也被称为后缀表示法。逆波兰记法不需要括号来确定的操作符的优先级。波兰逆表示的是易于使用的堆栈的结构分析和计算的表达,所以在这里我们分析表达的四要素,是第一个从中缀表达式转换为逆波兰表达式来计算价值。

两。转换过程

中缀表达式转换成后缀表达式(现场调度算法)

1。输入队列弹出一个标记。

2。如果标记是一个数字,则添加到输出队列中。

三.如果一个操作符(+与操作符比较)是堆栈输出堆栈的顶部,如果优先级小于或等于堆栈操作符的顶部,那么堆栈操作符的顶部加上输出队列(弹出循环,直到条件不满足),最后是操作符堆栈。

4。如果是左括号,则将堆栈压入堆栈中。

5。如果它是一个右括号,从堆栈中弹出的连续操作,并输出队列,知道在栈顶元素是左括号,左括号是冒出来的,与输出队列是不加的。如果左括号中不难发现,它表明,在原有的表达圆括号是不对称的和错误的。

6。如果输入队列是空的,运算符在堆栈中有一个操作符,如果堆栈顶部的操作符是左括号,则原始表达式有一个不匹配的括号,堆栈中的操作符一个接一个地弹出,并添加到输出队列中。

7。完成





三。转换代码的实现


功能操作人员(值){
无功operatorstring =+ - * /();
返回operatorstring.indexof(价值)> 1
}

功能getprioraty(值){
开关(值){
+案:
案例-:
返回1;
*案例:
案例:
返回2;
违约:
返回0;
}
}

功能prioraty(O1,O2){
返回getprioraty(O1)< = getprioraty(O2);
}

功能dal2rpn(EXP){
无功输入= { };
无功outputstack = { };
无功outputqueue = { };

对于(var i = 0,len = exp.length;我< len;i++){
var;
如果(当前)!=){
InputStack.push(CUR);
}
}
console.log('step一);
而(inputstack.length > 0){
无功电流= inputstack.shift();
如果(操作人员(CUR)){
如果(={({))
OutputStack.push(CUR);
否则,(如果为{))
VaR宝= outputstack.pop();
当(PO)!= '(' outputStack.length > 0) {
OutputQueue.push(PO);
宝= outputstack.pop();
}
如果(PO)!=){
抛出错误:未匹配();
}
其他{ }
而(prioraty(狗,outputstack { 1 } outputstack.length)outputstack.length > 0){
OutputQueue.push(outputstack.pop());
}
OutputStack.push(CUR);
}
其他{ }
OutputQueue.push(新号码(CUR));
}
}
console.log('step二);
如果(outputstack.length > 0){
如果(outputstack { 1 } outputstack.length = =)outputstack { 1 } outputstack.length(| | = ={)
抛出错误:未匹配();
}
而(outputstack.length > 0){
OutputQueue.push(outputstack.pop());
}
}
console.log('step三);
返回outputqueue;

}

console.log(dal2rpn(1 + 2));
console.log(dal2rpn(1 + 2 + 3));
console.log(dal2rpn(1 + 2 * 3));
console.log(dal2rpn(1+2×3-4 / 5));
console.log(dal2rpn('('(1 + 2)'));

console.log('('('('(1 + 2)×(3-4) / 5)(dal2rpn)));
console.log(dal2rpn('('(1 + 2)*((3-4) / 5))))


四,逆波兰表达式求值

1。从输入队列中弹出一个标记。

2。如果是操作数,则添加输出堆栈。

三.如果它是一个操作符,则从输出堆栈中弹出两个操作数并进行计算,计算值被压入输出堆栈中。

4。循环操作,如果输入队列为空,输出堆栈只有一个数字,则为结果,否则出现多余的操作数。

五。计算代码


Function evalRpn (rpnQueue) {
无功outputstack = { };
而(rpnqueue.length > 0){
无功电流= rpnqueue.shift();

如果(!操作人员(CUR)){
OutputStack.push(CUR);
其他{ }
如果(outputstack.length<2){
把无效栈长度;
}
VaR秒= outputstack.pop();
VaR FIR = outputstack.pop();

OutputStack.push(getResult(FIR,秒,Cur));
}
}

如果(outputstack.length!= 1){
把无效表达;
其他{ }
返回outputstack { 0 };
}
}



六。结论

波兰逆表示,在最初的接触感觉不习惯,但熟悉之后,会发现其实思想很简单,不像中缀表示法,有各种各样的优先啊,有一个小的支架等,逻辑特别麻烦,或反波兰表示相对简单的,不需要考虑优先,没有小括号、中括号和大括号扰流板。