表达式的计算

算术表达式的计算

步骤

  1. 中缀表达式转换为后缀表达式

从中缀表达式中从左往右依次取出数据 如遇到操作数,直接输出到后缀的队列里。 如果遇到操作符(包括括号),这里再定义一个存放操作符的栈,则:
i.如果操作符是’(’,入栈 ii.如果操作符是’)’,则把栈里的操作符依次出栈并插入到后缀序列后面,直到遇到’(’.
iii.如果操作符不是‘(’和‘)’,则:
(1).当前操作符优先级高于操作符栈顶元素时入栈
操作符栈为空时 入栈
操作符栈顶元素是’('时入栈
(2)优先级小于或等于 取栈顶元素到后缀集合中 并出栈 重复以上操作至此操作符入栈

  1. 计算后缀表达式

从左到右一个个遍历表达式,遇到操作数就入栈,遇到操作符就依次取出栈顶的两个操作数进行计算,并把计算结果入栈,供后面计算,直到栈为空,说明表达式计算完毕,否则说明表达式有问题

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++;
			}
		}
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值