算术表达式的计算
步骤
- 中缀表达式转换为后缀表达式
从中缀表达式中从左往右依次取出数据 如遇到操作数,直接输出到后缀的队列里。 如果遇到操作符(包括括号),这里再定义一个存放操作符的栈,则:
i.如果操作符是’(’,入栈 ii.如果操作符是’)’,则把栈里的操作符依次出栈并插入到后缀序列后面,直到遇到’(’.
iii.如果操作符不是‘(’和‘)’,则:
(1).当前操作符优先级高于操作符栈顶元素时入栈
操作符栈为空时 入栈
操作符栈顶元素是’('时入栈
(2)优先级小于或等于 取栈顶元素到后缀集合中 并出栈 重复以上操作至此操作符入栈
- 计算后缀表达式
从左到右一个个遍历表达式,遇到操作数就入栈,遇到操作符就依次取出栈顶的两个操作数进行计算,并把计算结果入栈,供后面计算,直到栈为空,说明表达式计算完毕,否则说明表达式有问题
import java.util.ArrayList;
import java.util.Scanner;
import java.util.Stack;
//以String类型处理 上一个的改进
//计算表达式
/*
* 中缀表达式转为后缀表达式
* 计算后缀表达式
*
* 中缀:12*(3+4)-6+6/2
* 后缀:[1, 2, 3, 4, +, *, 6, -, 6, 2, /, +]
*/
public class 算术表达式1 {
static Stack<Character> stack = new Stack<Character>();
static ArrayList<String> array1 = new ArrayList<String>();// 中缀
static ArrayList<String> array2 = new ArrayList<String>();// 后缀
public static void main(String[] args) {
// array1.add("12");
// array1.add("*");
// array1.add("(");
// array1.add("3");
// array1.add("+");
// array1.add("4");
// array1.add(")");
// array1.add("-");
// array1.add("6");
// array1.add("+");
// array1.add("8");
// array1.add("/");
// array1.add("2");
// Change(0);
// System.out.println(array2);
// System.out.println(Calucate());
//String s="(123-23)*3-80*(80-40)";
Scanner sc=new Scanner(System.in);
String string=sc.nextLine();
method3(string);
Change(0);
System.out.println(Calucate());
//System.out.println(array1);
}
// 中缀表达式转后缀表达式
public static void Change(int i) {
if (i < array1.size()) {
String index = array1.get(i);
if (index.equals("(")) {//为( 直接入操作符栈 以下称入栈
stack.push(index.charAt(0));
} else if (index.equals(")")) {//为) 将栈内操作符移除并加入到后缀表达式中,直到遇到( 且要出栈
while (stack.peek() != '(') {
String str = String.valueOf(stack.pop());
array2.add(str);
}
stack.pop();
//为操作符 需要比较优先级
} else if (index.equals("+") || index.equals("-") || index.equals("*") || index.equals("/")) {
method(index.charAt(0));
} else {//操作数直接添加到后缀表达式中
array2.add(index);
}
Change(i + 1);// 递归 用循环也可以
} else {// 遍历完了中缀表达式 若此时操作符栈内还有元素 都一次添加到后缀表达式中
while (!stack.isEmpty()) {
String index = String.valueOf(stack.pop());
array2.add(index);
}
}
}
// 判断操作符优先级
static boolean is(char a, char b) {
if ((a == '*' || a == '/') && (b == '+' || b == '-'))
return true;// a优先与b
return false;
}
static void method(char c) {
if (!stack.isEmpty()) {
// 当前操作符优先级高于操作符栈顶元素时入栈
// 操作符栈为空时 入栈
// 操作符栈顶元素是'('时入栈
if (is(c, stack.peek()) || stack.peek() == '(') {
stack.push(c);
return;
}
// 优先级小于或等于 取栈顶元素到后缀集合中 并出栈 重复以上操作至此操作符入栈
String index = String.valueOf(stack.pop());
array2.add(index);
method(c);
} else {
stack.push(c);
}
}
static int Calucate() {//计算
Stack<Integer> stack_1 = new Stack<Integer>();// 存储操作数与结果
for (int i = 0; i < array2.size(); i++) {
String index = array2.get(i);
//为操作符 去栈顶两个元素(出栈)进行计算 并压入栈顶
if (index.equals("+") || index.equals("-") || index.equals("*") || index.equals("/")) {
int a = stack_1.pop();
int b = stack_1.pop();
// System.out.println(index.charAt(0));
stack_1.push(method1(index.charAt(0), b, a));//a和b的顺序不能反
System.out.println("---");
// System.out.println(stack_1.peek());
// System.out.println("---");
} else {//不是操作符直接入栈
// System.out.println(Integer.parseInt(index));
stack_1.push(Integer.parseInt(index));
}
}
int result = stack_1.pop();
if (stack_1.isEmpty())//不为空说明表达式有问题
return result;
return -11111;
}
static int method1(char index, int a, int b) {//更具操作符计算
switch (index) {
case '+':
return a + b;
case '-':
return a - b;
case '*':
return a * b;
case '/':
return a / b;
}
return 0;
}
//将字符串转化为中缀表达式 (将表达式进行拆分 数字与操作符分开)
static void method3(String str) {
for(int i=0;i<str.length();) {
char index=str.charAt(i);
if(index>='0'&&index<='9') {
int j;
if(i==str.length()-1) {
array1.add(String.valueOf(index));
}
for(j=i+1;j<str.length();j++) {
if(!(str.charAt(j)>='0'&&str.charAt(j)<='9')) {
String s=str.substring(i, j);
array1.add(s);
break;
}
}
i=j;
}else {
array1.add(String.valueOf(index));
i++;
}
}
}
}