蓝桥杯: 算法训练 表达式计算
问题描述
输入一个只包含加减乖除和括号的合法表达式,求表达式的值。其中除表示整除。
输入格式
输入一行,包含一个表达式。
输出格式
输出这个表达式的值。
样例输入
1-2+3*(4-5)
样例输出
-4
数据规模和约定
表达式长度不超过100,表达式运算合法且运算过程都在int内进行。
package qiao;
import java.util.*;
//计算 2*(4+(88-86)/2)
class caculater{
private String[] sArry;//存分割后的字符串
private Stack<String> houx = new Stack<String>();
private Stack<String> fuhao = new Stack<String>();
//结构初始化
caculater(String getin){
int i = getin.length()-1;
String temp = new String();
int j = 0;
Boolean bool = true;
//在符号左右各添加一个#字符划分
while(bool){
if(i==j){
bool = false;
}
if(getin.charAt(j)=='+'
||getin.charAt(j)=='-'
||getin.charAt(j)=='*'
||getin.charAt(j)=='/'
||getin.charAt(j)=='('
||getin.charAt(j)==')'){
temp += '#';
temp += getin.charAt(j);
temp += '#'; //填完后是2#*##(#4#+##(#88#-#86#)##/#32#)#
}else{
temp += getin.charAt(j);
}
j++;
}
sArry = temp.split("#+");//用正则表达式分割成字符串,#+表示一个或多个#字符//结果:[2,*,(,4,+,(,88,-,85,),/,2,)]
}
//后序排列
public void backsort(){
//循环sArry
for(int i= 0;i<sArry.length;i++){
//如果不是字符,就直接push入houx栈
if(!sArry[i].equals("+")
&&!sArry[i].equals("-")
&&!sArry[i].equals("*")
&&!sArry[i].equals("/")
&&!sArry[i].equals("(")
&&!sArry[i].equals(")")){
houx.push(sArry[i]);
continue;
//否则是字符,若符号栈为空,直接入栈
}else if(fuhao.isEmpty()){
fuhao.push(sArry[i]);
continue;
//如果为(括号,直接入符号栈
}else if(sArry[i].equals("(")){
fuhao.push(sArry[i]);
continue;
//如果为)括号
}else if(sArry[i].equals(")")){
/**
* 不断出栈直到(括号出现
*
*/
while(!fuhao.peek().equals("(")){
houx.push(fuhao.pop());
}
fuhao.pop();//清掉(括号
//如果不为空,且要入的符号比符号栈顶的符号优先级高,则直接push入符号栈
}else if(!fuhao.isEmpty()&&check(sArry[i],fuhao.peek())){ //
fuhao.push(sArry[i]);
continue;
//否则,将符号栈内优先级高的符号出栈,push入houx栈,再将符号存进符号栈
}else{
houx.push(fuhao.pop());
fuhao.push(sArry[i]);
continue;
}
}
//遍历完后,直接将符号栈内的依次出栈,push入houx栈
while(!fuhao.isEmpty()){
houx.push(fuhao.pop());
}//结果是:2 4 88 86 - 2 / + * 栈内顺序
}
//check对比优先级
private boolean check(String a,String b){
//如果符号栈内是(括号,直接返true
if(b.equals("(")){
return true;
}
//如果符号栈内的优先级比要入的高,返回false
if((b.equals("*")||b.equals("/"))&&(a.equals("+")||a.equals("-"))){ //b>a
return false;
}
//。。。。。。。。。。。。。的低,返回true
if((b.equals("+")||b.equals("-"))&&(a.equals("*")||a.equals("/"))){ //b<a
return true;
}
return false;
}
//出栈计算
public void suan(){
backsort();//后序排列
//结果栈end
Stack<Integer> end = new Stack<Integer>();
//遍历houx栈
for(int i=0; i<houx.size();i++){
//如果是加号,end pop出来两个数字,计算后结果入栈
if(houx.get(i).equals("+")){
int b = end.pop();
int a = end.pop();
end.push(a+b);
continue;
//如果是减号,end pop出栈两个数字,计算后结果入栈
}else if(houx.get(i).equals("-")){
int b = end.pop();
int a = end.pop();
end.push(a-b);
continue;
//如果是乘号,end pop出栈两个数字,计算后结果入栈
}else if(houx.get(i).equals("*")){
int b = end.pop();
int a = end.pop();
end.push(a*b);
continue;
//如果是除号,end pop出栈两个数字,计算后结果入栈
}else if(houx.get(i).equals("/")){
int b = end.pop();
int a = end.pop();
end.push(a/b);
continue;
}else{
//不是符号,也就是数字的情况,Integer.parseInt转int型, push入栈
end.push(Integer.parseInt(houx.get(i)));
}
}
//输出结果
System.out.println(end.pop());
}
}
public class BiaodashijisuanDemo {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
//获取输入
String getin = sc.nextLine();
//结构化
caculater cl = new caculater(getin);
//计算
cl.suan();
sc.close();
}
}
看了一遍书后,按着自己的理解写了一遍。对比之前自己的渣渣写法要好到不知道哪里去了。
英语还是很蛋疼,变量名都是起的拼音(╥╯^╰╥)