您的位置:首页 > 其它

逆波兰表达式原理实现

2017-11-10 16:33 239 查看
解析原理如下:(1) 该运算符为左括号"(",则直接存入运算符堆栈。      (2) 该运算符为右括号")",则输出运算符堆栈中的运算符到操作数堆栈,直到遇到左括号为止,此时抛弃该左括号。      (3) 该运算符为非括号运算符:      (a) 若运算符堆栈栈顶的运算符为左括号,则直接存入运算符堆栈。      (b) 若比运算符堆栈栈顶的运算符优先级高,则直接存入运算符堆栈。      (c) 若比运算符堆栈栈顶的运算符优先级低或相等,则输出栈顶运算符到操作数堆栈,直至运算符栈栈顶运算符低于(不包括等于)该运算符优先级,或为左括号,           并将当前运算符压入运算符堆栈。具体实现:
package com.example.admin.myapplication;

import android.os.Build;
import android.support.annotation.RequiresApi;
import android.text.TextUtils;
import android.util.Log;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Stack;

/**
* Created by admin on 2017/11/8.
* 逆波兰算法实现
* 仅支持 + - * /
*/

public class NBLArithmetic {
private enum Operator {
ADD("+", 1),
SUBJECT("-", 1),
RIDE("*", 2),
DIVIDE("/", 2),
BRACKET_L("(", 0),
BRACKET_R(")", 0),;

Operator(String value, int weight) {
this.value = value;
this.weight = weight;
}

String value;
int weight;

public String getValue() {
return value;
}

public int getWeight() {
return weight;
}

static Operator fromValue(String value) {
Operator[] values = values();
for (Operator val : values) {
if (value.equals(val.getValue())) {
return val;
}
}
return null;

}

}

/**
* 运算符栈
*/
private Stack<Operator> operatorStack;
/**
* 操作数栈
*/
private Stack<Integer> operandStack;
/**
* 临时存储区,存放逆波兰运算中间结果
*/
private LinkedList<String> cacheQueue;

@RequiresApi(api = Build.VERSION_CODES.GINGERBREAD)
public NBLArithmetic() {
operatorStack = new Stack<>();
operandStack = new Stack<>();
cacheQueue = new LinkedList<>();
}

/**
* 计算结果
*
* @param operation
*/
public void opera(String operation) {
List<String> operas = getArrayFormOperation(operation);
for (String opera : operas) {
if (TextUtils.isDigitsOnly(opera)) {
cacheQueue.add(opera);
} else {
Operator operator = Operator.fromValue(opera);
Operator lastOperator = operatorStack.empty() ? null : operatorStack.peek();
if (lastOperator == null || lastOperator == Operator.BRACKET_L || operator == Operator.BRACKET_L) {
operatorStack.push(operator);
} else {
switch (operator) {
case ADD:
case RIDE:
case DIVIDE:
case SUBJECT:
while (lastOperator != null && operator.getWeight() <= lastOperator.getWeight()) {//栈顶优先级大于等于本次操作符
cacheQueue.add(operatorStack.pop().getValue());
lastOperator = operatorStack.empty() ? null : operatorStack.peek();
}
operatorStack.push(operator);
break;
case BRACKET_R:
while (lastOperator != null && lastOperator != Operator.BRACKET_L) {
cacheQueue.add(operatorStack.pop().getValue());
lastOperator = operatorStack.empty() ? null : operatorStack.peek();
}
operatorStack.pop();
break;
}
}
}
}
while (!operatorStack.isEmpty()) {
cacheQueue.add(operatorStack.pop().getValue());
}

//-----------------------开始计算---------------------------------------------------

while (cacheQueue.size() > 0) {
String data = cacheQueue.removeFirst();
if (TextUtils.isDigitsOnly(data)) {
operandStack.push(Integer.parseInt(data));
} else {
Operator operator = Operator.fromValue(data);
int b = operandStack.pop();
int a = operandStack.pop();
switch (operator) {
case ADD:
operandStack.push(a + b);
break;
case RIDE:
operandStack.push(a * b);
break;
case DIVIDE:
operandStack.push(a / b);
break;
case SUBJECT:
operandStack.push(a - b);
break;
}
}
}

Log.i("NBL", operation + " = " + operandStack.pop());
}

/**
* 解析表达式成array
*
* @param operation
* @return
*/
private List getArrayFormOperation(String operation) {
List operaList = new ArrayList();
char[] chars = operation.toCharArray();
StringBuffer sb = new StringBuffer();
for (char a : chars) {
if (TextUtils.isDigitsOnly(a + "")) {
sb.append(a + "");
} else if (".".equals(a + "")) {
sb.append(a + "");
} else {
if (sb.length() > 0) {
operaList.add(sb.toString());
}
operaList.add(a + "");
sb.delete(0, sb.length());
}
}
if (sb.length() > 0) {
operaList.add(sb.toString());
}
return operaList;
}

}
使用很方便:
new NBLArithmetic().opera("3+4*(3-5)*2");new NBLArithmetic().opera("3+4*(3-5)*2+56");new NBLArithmetic().opera("3+4*(3-5)*2+56-3*2");new NBLArithmetic().opera("3+4*(3-5)*2+56-3*2+(2-8)*4");new NBLArithmetic().opera("56-3+(2-8)*4");new NBLArithmetic().opera("3+4*(3-5)*2+56-3*2+(2-8)*4");
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: