蓝桥杯-表达式求值(Dijkstra双栈)
2018-01-30 11:29
218 查看
package jiChu; import java.util.ArrayList; /** 问题描述 输入一个只包含加减乖除和括号的合法表达式,求表达式的值。其中除表示整除。 输入格式 输入一行,包含一个表达式。 输出格式 输出这个表达式的值。 样例输入 1-2+3*(4-5) 样例输出 -4 数据规模和约定 表达式长度不超过100,表达式运算合法且运算过程都在int内进行。 */ import java.util.Scanner; import java.util.Stack; public class TTTTTTTT { public static void main(String[] args) { Scanner input=new Scanner(System.in); Stack<Integer> nums=new Stack<Integer>(); //保存数据 Stack<Character> opes=new Stack<Character>(); //保存运算符 String str=input.nextLine(); //输入表达式 input.close(); char[] arr=str.toCharArray(); //转换为字符数组,如果数字大于9,则该数字占的字符位数大于1 int n=0; for (int i = 0; i < arr.length; i++) { char temp=arr[i]; if (Character.isDigit(arr[i])) { //判断arr[i]是否为数字 n=n*10+Integer.parseInt(String.valueOf(arr[i])); //如果数字大于10,会一直循环下去,知道把数字全部取出 }else { if (n!=0) { //当前的arr[i]不是数字了,但是因为前边存储过数字,所以n不为0,得清空 nums.push(n); //表达式中间的数据入栈 n=0; } if (temp=='(') { opes.push(temp); }else if (temp==')') { //右括号,开始计算 while(opes.peek()!='('){ //如果栈顶不是左括号 int t=cal(nums.pop(), nums.pop(), opes.pop()); nums.push(t); } opes.pop(); //将没有用的左括号出栈 }else if (isType(temp)>0) { //判断优先级,优先级小的入栈 if (opes.isEmpty()) { //栈为空,temp进栈 opes.push(temp); }else { //栈不为空,与栈顶进行判断 if (isType(opes.peek())>=isType(temp)) { //如果栈顶的运算符优先级大于temp,出栈进行运算 int t=cal(nums.pop(), nums.pop(), opes.pop()); //计算的优先级高的 nums.push(t); //将计算结果进入nums栈 } opes.push(temp);//再将temp入栈 } } } } if(n!=0) nums.push(n); //表达式最后剩余的数字入栈,和循环中的数据入栈作用一样 while (!opes.isEmpty()) { //运算符栈不为空,表达式未求完值,该栈一定不为空 int t=cal(nums.pop(), nums.pop(), opes.pop()); //该循环计算的都是优先级一样的比如+-,所以计算顺序不要求,高的比如*/在存储时已经计算完了 nums.push(t); //将计算的数据再存入 } System.out.println(nums.pop()); //计算结束数据栈会存储最后一个结果 } //判断 + - * /的优先级,设置等级 private static int isType(char c) { if (c=='+'||c=='-') { //优先级低 return 1; }else if (c=='*'||c=='/') { //优先级高 return 2; }else { return 0; } } //运算符的运算 m表示后面的数字,n表示前面的数字,不要反了 private static int cal(int m, int n, char c) { // TODO Auto-generated method stub int sum=0; if (c=='+') { sum=n+m; }else if (c=='-') { sum=n-m; }else if (c=='*') { sum=n*m; }else if (c=='/') { sum=n/m; } return sum; } }
1.Character.isDigit(char变量)可以判断是否是数字字符;
2.栈的peek()方法是取栈顶,但是不会删除元素;
该算法和上一个的区别是,上一个需要用括号将表达式全部包起来,不适于人们普通写的表达式,而这个算法是和人们通常写的是一样的。
相关文章推荐
- 算法-表达式求值(Dijkstra双栈)
- 算法(第四版) Dijkstra 算数表达式求值算法-双栈
- Dijkstra双栈表达式求值算法
- Dijkstra的双栈算术表达式的求值算法
- Dijkstra的双栈算术表达式的求值算法
- 栈的一个小应用——Dijkstra的双栈算术表达式
- 使用双栈实现表达式求值
- 【蓝桥杯-基础训练】*+表达式求值
- 使用双栈实现表达式求值
- 《算法》第一章——Dijkstra双栈表达式求值
- Dijkstra的双栈算法表达式求值算法
- 表达式求值(蓝桥杯)
- 蓝桥杯 算法训练 表达式的计算(中缀转后缀表达式求值)
- 【算法】E.W.Dijkstra算术表达式求值
- Dijkstra的双栈算数表达式求值算法
- Dijkstra 的双栈算数表达式求值算法的学习
- 表达式求值
- 中缀表达式转换成后缀表达式并求值
- [C] 关于表达式求值
- 表达式求值