您的位置:首页 > 其它

蓝桥杯-表达式求值(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()方法是取栈顶,但是不会删除元素;

该算法和上一个的区别是,上一个需要用括号将表达式全部包起来,不适于人们普通写的表达式,而这个算法是和人们通常写的是一样的。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: