将中缀表达式转换为后缀表达式
2016-12-27 00:12
246 查看
中缀表达式:(6/2*3+9)/2+(3+1-1)*3+10/2
后缀表达式:6 2 / 3 * 9 + 2 / 3 1 + 1 - 3 * +10 2 / +
转换顺序如下:
![](file:///C:\Users\Administrator\AppData\Roaming\Tencent\Users\332869825\QQ\WinTemp\RichOle\FG]Y(K_`8N]ZPJ~X7SB%6$0.png)
![](file:///C:\Users\Administrator\AppData\Roaming\Tencent\Users\332869825\QQ\WinTemp\RichOle\FG]Y(K_`8N]ZPJ~X7SB%6$0.png)
![](http://img.blog.csdn.net/20161227000815129?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQveWF3aW5zdGFrZQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
实现代码如下,可直接运行,仅供测试使用,可能还存在bug。
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/
后缀表达式:6 2 / 3 * 9 + 2 / 3 1 + 1 - 3 * +10 2 / +
转换顺序如下:
![](file:///C:\Users\Administrator\AppData\Roaming\Tencent\Users\332869825\QQ\WinTemp\RichOle\FG]Y(K_`8N]ZPJ~X7SB%6$0.png)
![](file:///C:\Users\Administrator\AppData\Roaming\Tencent\Users\332869825\QQ\WinTemp\RichOle\FG]Y(K_`8N]ZPJ~X7SB%6$0.png)
实现代码如下,可直接运行,仅供测试使用,可能还存在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/
相关文章推荐
- 中缀表达式转换为后缀表达式
- 中缀表达式转换成后缀表达式
- [ZZ]中缀表达式转换成前缀表达式和后缀表达式
- 中缀表达式转换成前缀表达式和后缀表达式的极其简单方法
- 【综合】中缀表达式转换成后缀表达式后,用后缀表达式计算出结果
- 中缀表达式转换成后缀表达式
- 栈的应用— 中缀表达式到后缀表达式的转换
- 中缀表达式转换为后缀表达式
- 利用栈将中缀表达式转换成后缀表达式
- 中缀表达式转换成前缀表达式和后缀表达式
- 中缀表达式转换为后缀表达式
- 中缀表达式转换为后缀表达式
- [整合]中缀表达式、前缀表达式、后缀表达式的相互转换
- PTA 表达式转换 算术表达式有前缀表示法、中缀表示法和后缀表示法等形式。日常使用的算术表达式是采用中缀表示法,即二元运算符位于两个运算数中间。请设计程序将中缀表达式转换为后缀表达式。
- 中缀表达式转换为后缀表达式&后缀表达式的计算
- 中缀表达式转换成为后缀表达式
- 后缀表达式转换为中缀表达式
- 利用JAVA实现中缀表达式向后缀表达式的转换,并求出表达式的值
- 中缀表达式转换为后缀表达式
- 括号匹配问题 中缀表达式转换为后缀表达式