https://blog.csdn.net/huangpingcai/article/details/73864521
两个stack ,一个opeateStack,一个outputStack
可以把左括号的 优先级调最小,因为左括号的情况,都是push的
if (c 非操作符){
outputStack.push(c)
}
if(c 操作符:左括号){
opeateStack.push(c)
}
if(opeateStack 是空){
opeateStack.push(c)
}
if(c 操作符:右括号){
从opeateStack 取出直到左括号为止 ,放入outputStack
}
if(c 操作符 优先级 比 opeateStack 第一个 高){
opeateStack.push(c)
}
if(c 操作符 优先级 比 opeateStack 第一个 低){
取出opeateStack中比c优先级高的或者相等的,放入outputStack
}
I am here in accordance with the above logic to achieve:
package coveragetest;
import java.util.*;
import java.util.regex.Matcher;
public class HisTest {
private static Map<String,Integer> priorityMap = new HashMap<String, Integer>();
private String expressStr ;
private Map valueMap = new HashMap();
//拆解后
private List<Object> itemList = new ArrayList();
//操作符 stack
Stack<Object> operateStack = new Stack();
//组装后stack
Stack<Object> outputStack = new Stack();
//结果
Stack<Object> resultStack = new Stack();
public HisTest(String expressStr,Map valueMap){
this.expressStr = expressStr;
this.valueMap = valueMap;
}
static {
priorityMap.put("+",10);
priorityMap.put("-",10);
priorityMap.put("*",20);
priorityMap.put("/",20);
priorityMap.put("(",30);
priorityMap.put(")",30);
priorityMap.put("equal",10);
priorityMap.put("notequal",10);
priorityMap.put("startith",10);
priorityMap.put("=",10);
priorityMap.put("and",5);
priorityMap.put("or",5);
priorityMap.put("not",10);
priorityMap.put("!=",10);
}
private Boolean isOperate(String c){
c= c.toLowerCase();
return priorityMap.containsKey(c);
}
private boolean isRightBracket(String c){
return c.equals(")");
}
private boolean isLeftBracket(String c){
return c.equals("(");
}
private boolean hightPriority(Object c,Object stackObject){
return priorityMap.get(String.valueOf(c)) > priorityMap.get(String.valueOf(stackObject));
}
private boolean equalPriority(Object c,Object stackObject){
return priorityMap.get(String.valueOf(c)) == priorityMap.get(String.valueOf(stackObject));
}
/**
* 中缀表达式转化为后缀表达式
*/
public void convertAfter(){
for(Object c : itemList){
//是否操作
if(!isOperate(String.valueOf(c))){
if(valueMap.containsKey(c.toString())){
outputStack.push(valueMap.get(c));
}else{
outputStack.push(c);
}
continue;
}
if(operateStack.isEmpty()){
operateStack.push(c);
continue;
}
if(isLeftBracket(operateStack.peek().toString())){
operateStack.push(c);
continue;
}
if(isRightBracket(c.toString())){
while(true){
if(!operateStack.isEmpty()){
Object v = operateStack.pop();
if(isLeftBracket(v.toString())){
break;
}
outputStack.push(v);
}else{
break;
}
}
continue;
}
if(hightPriority(c,operateStack.peek())){
operateStack.push(c);
}else{
Object v = operateStack.peek();
if(isLeftBracket(v.toString())){
operateStack.push(c);
}else{
while(true){
if(!operateStack.isEmpty()){
Object v2 = operateStack.peek();
if(equalPriority(c,v2) || hightPriority(v2,c)){
if(!isLeftBracket(v2.toString())){
outputStack.push(v2);
operateStack.pop();
}else{
break;
}
}else{
break;
}
}else{
break;
}
}
}
operateStack.push(c);
}
}
for(Object cc : operateStack){
outputStack.push(cc);
}
for(Object cc : outputStack){
System.out.println("---"+cc);
}
}
/**
* 计算
*/
public Object calcu(){
for(Object c : outputStack){
if(isOperate(c.toString())){
Object o2 = resultStack.pop();
if(c.toString().equals("=")){
Object o1 = resultStack.pop();
resultStack.push(Integer.parseInt(o1.toString())==Integer.parseInt(o2.toString()));
}else if(c.toString().equals("equal")){
Object o1 = resultStack.pop();
resultStack.push(o1.toString().equals(o2.toString()));
}else if(c.toString().equals("and")){
Object o1 = resultStack.pop();
resultStack.push((Boolean)o1 && (Boolean) o2);
}else if(c.toString().equals("or")){
Object o1 = resultStack.pop();
resultStack.push((Boolean)o1 || (Boolean) o2);
}else if(c.toString().equals("notequal")){
Object o1 = resultStack.pop();
resultStack.push(!o1.toString().equals(o2.toString()));
}else if(c.toString().equals("not")){
resultStack.push(!(Boolean)o2);
}
}else{
resultStack.push(c);
}
}
return resultStack.pop();
}
public void seperateCharsToItems(){
int length = this.expressStr.length();
int charAtInt = 0;
boolean isComplete = true;
StringBuffer temp = new StringBuffer();
while(true){
if(length == charAtInt){
break;
}
char c = this.expressStr.charAt(charAtInt);
charAtInt++;
if(isComplete){
if( c == ' ' ){
if(temp.toString().length() > 0){
itemList.add(temp.toString());
temp = new StringBuffer();
}
continue;
}
if(isOperate(String.valueOf(c))){
if(temp.toString().length() > 0){
itemList.add(temp.toString());
temp = new StringBuffer();
}
itemList.add(c);
continue;
}
if( c == '\''){
isComplete = false;
continue;
}
if(c == '('){
itemList.add(c);
continue;
}
if(c == ')'){
itemList.add(c);
continue;
}
temp.append(c);
}else{
if( c =='\''){
isComplete = true;
itemList.add(temp.toString());
temp = new StringBuffer();
continue;
}
temp.append(c);
continue;
}
}
for(Object v : itemList){
System.out.println(v);
}
}
public Object execParse(){
seperateCharsToItems();
//转化
this.convertAfter();
//计算
System.out.println("^^^^^^^^^^^"+this.calcu());
//返回
return null;
}
//切割
public static void main(String[] args) {
Map valueMap = new HashMap();
valueMap.put("data.a",30);
valueMap.put("data.c",20);
valueMap.put("e","11");
valueMap.put("d","10");
//String expressStr = " (data.a=40 and data.c=20) or (e equal '111' and d notequal '朱 b 春燕') ";
String expressStr = " data.a = 30 and not (data.c = 30) ";
HisTest test = new HisTest(expressStr,valueMap);
test.execParse();
}
}