中缀表达式:(6/2*3+9)/2+(3+1-1)*3+10/2
后缀表达式:6 2 / 3 * 9 + 2 / 3 1 + 1 - 3 * +10 2 / +
转换顺序如下:
实现代码如下,可直接运行,仅供测试使用,可能还存在bug。
package com.example;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import java.util.Stack;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Created by Yawinstake on 2016/12/25
*/
/**
* only support Integer
*/
public class CalcTest {
private final String[] TAGS = new String[]{"+","-","*","/","(",")"};
//缓存中缀表达式解析结果
private final List<String> CACHE_INFIX = new ArrayList<>();
//缓存后缀表达式结果
private final List<String> CACHE_SUFFIX = new ArrayList<>();
//用于解析后缀表达式中间栈
private final Stack<String> tempStack = new Stack<>();
//用于计算最终结果栈,最后只剩下一个数据时即为计算结果
private final Stack<Double> calcStack = new Stack<>();
public static void main(String[] args){
Scanner scanner = new Scanner(System.in);
String input = scanner.nextLine();
new CalcTest().calculateTest(input);
}
public void calculateTest(String s){
if(s == null){
return;
}
split(s);
String[] args_infix = CACHE_INFIX.toArray(new String[CACHE_INFIX.size()]);
System.out.println("parse infix data:"+printStringArray(args_infix));
translate(args_infix);
String[] args_suffix = CACHE_SUFFIX.toArray(new String[CACHE_SUFFIX.size()]);
System.out.println("suffix data:"+printStringArray(args_suffix));
System.out.println("calc result is:"+calculateUseSuffix(args_suffix));
}
private double calculateUseSuffix(String[] args_suffix){
if(args_suffix == null || args_suffix.length == 0){
return 0;
}
//遇到符号则将其前两位置数字进行运算
for(int i= 0;i<args_suffix.length;i++){
if(isNumeric(args_suffix[i])){
calcStack.push(Double.parseDouble(args_suffix[i]));
}else{
double number2 = calcStack.pop();
double number1 = calcStack.pop();
double result = calc(number1,number2,args_suffix[i]);
calcStack.push(result);
}
}
return calcStack.pop();
}
private double calc(double number1, double number2,String operator){
if( operator== null){
return 0f;
}
try{
if(operator.equals("+")){
return number1 + number2;
}else if(operator.equals("-")){
return number1 - number2;
}else if(operator.equals("*")){
return number1 * number2;
}else if(operator.equals("/")){
return number1 / number2;
}
}catch (Exception e){
}
return 0f;
}
//可以修改此方法支持其他类型
public boolean isNumeric(String s){
if(s == null || s.trim().length() == 0){
return false;
}
Pattern mPattern = Pattern.compile("[0-9]*");
Matcher matcher = mPattern.matcher(s);
return matcher.matches();
}
/**
* 将中缀表达式转换为后缀表达式
* @param args
*/
private void translate(String[] args){
if(args == null || args.length == 0){
return;
}
for(int i=0;i<args.length;i++){
String arg = args[i];
//数字输出,运算符进栈,括号匹配出栈,栈顶优先级低出栈
if(isTag(arg)){
if(arg.equals(")")){
//should pop
while(!tempStack.empty()){
String popTag = tempStack.pop();
if(popTag.equals("(")){
break;
}
addToSuffix(popTag);
}
}else {
/**
* 判断栈内数据是否为空
* 不为空时循环取出栈顶数据与当前遍历数据比较优先级
* 结果为false时出栈,直到结果为true时退出循环
* 不论是否执行循环,最终都需要把当前的数据压入栈中
*/
while(!tempStack.empty()){
String topArg = tempStack.peek();
//
if(isTagHighPriorityToStackFirst(topArg,arg)) {
break;
}
String popTag = tempStack.pop();
addToSuffix(popTag);
}
tempStack.push(arg);
}
}else{
CACHE_SUFFIX.add(arg);
if(i == args.length - 1){
while(!tempStack.empty()){
String popTag = tempStack.pop();
addToSuffix(popTag);
}
}
}
System.out.println("arg is "+arg+",tempStack is"+tempStack+",CACHE_SUFFIX is "+CACHE_SUFFIX);
}
}
private void addToSuffix(String tag){
if(tag == null || tag.length() == 0){
return;
}
if(isTagCanAdd(tag)){
CACHE_SUFFIX.add(tag);
}
}
/**
*
* @param topTag 栈顶
* @param currentTag 当前数据
* @return
* 当栈顶为"("时,返回true
* 当栈顶优先级等于当前要入栈数据时,返回false
* 当栈顶优先级高于要入栈数据时,返回false
* 当栈顶优先级低于要入栈数据时,返回true
*/
private boolean isTagHighPriorityToStackFirst(String topTag , String currentTag){
if(topTag.equals(currentTag)){
return false;
}
if(topTag.equals("(")){
return true;
}
if(topTag.equals("*") || topTag.equals("/")){
return false;
}else{
if(currentTag.equals("+") || currentTag.equals("-")){
return false;
}
}
return true;
}
private boolean isTag(String s){
if(s == null || s.trim().length() == 0){
return false;
}
for(String tag : TAGS){
if(tag.equals(s)){
return true;
}
}
return false;
}
private boolean isTagCanAdd(String s){
if(s == null || s.trim().length() == 0){
return false;
}
for(String tag : TAGS){
if(tag.equals(s) && !tag.equals(")") && !tag.equals("(")){
return true;
}
}
return false;
}
private boolean isArgNotContainAnyTag(String arg){
for(String tag : TAGS){
if(arg.contains(tag)){
return false;
}
}
return true;
}
private static ArrayList<String> spitBytag(String s , String tag){
if(s == null || tag == null){
return null;
}
ArrayList<String> list = new ArrayList<>();
if(!s.contains(tag)){
list.add(s);
return list;
}
String[] args = s.split(changeTag(tag));
if(args.length == 1){
if(s.indexOf(tag) == 0){
list.add(tag);
list.add(args[0]);
}else {
list.add(args[0]);
list.add(tag);
}
}else {
for (String arg : args) {
//ignore space
if (arg != null && arg.trim().length() != 0) {
if (list.size() == 0) {
list.add(arg);
} else {
if(!list.get(list.size()-1).equals(tag)) {
list.add(tag);
}
list.add(arg);
}
}else{
list.add(tag);
}
}
}
// System.out.println("s is "+s+",tag is "+tag +",list is "+list+",args length is "+args.length);
return list;
}
private static String changeTag(String tag){
return "["+tag+"]";
}
private static String printStringArray(String[] array){
if(array == null){
return "";
}
StringBuilder sb = new StringBuilder();
for(String s : array){
if(sb.length() == 0){
sb.append(s);
}else{
sb.append(",").append(s);
}
}
return sb.toString();
}
private void split(String s){
split(s,0);
}
/**
* 采用递归
* @param s
* @param index
*/
private void split(String s,final int index){
if(index == TAGS.length){
return;
}
List<String> list = spitBytag(s,TAGS[index]);
if(list != null && list.size() > 0){
if(list.size() == 1){
String subS = list.get(0);
if (subS.length() == 1 || isArgNotContainAnyTag(subS)) {
CACHE_INFIX.add(subS);
}else{
split(subS,index+1);
}
}else {
for (String subS : list) {
if (subS != null) {
if (subS.length() == 1 || isArgNotContainAnyTag(subS)) {
CACHE_INFIX.add(subS);
}else{
split(subS,index+1);
}
}
}
}
}
}
}
执行结果:
parse infix data:(,6,/,2,*,3,+,9,),/,2,+,(,3,+,1,-,1,),*,3,+,10,/,2
suffix data:6,2,/,3,*,9,+,2,/,3,1,+,1,-,3,*,+,10,2,/,+
calc result is:23.0
部分内容参考了:http://blog.csdn.net/antineutrino/article/details/6763722/