• Java集合框架练习-计算表达式的值


    最近在看《算法》这本书,正好看到一个计算表达式的问题,于是就打算写一下,也正好熟悉一下Java集合框架的使用,大致测试了一下,没啥问题。

    import java.util.*;
    /*
     * 
     * 用来计算表达式
     * for example: 1+2*3*(4+3*1)-3*1+2+3/1;
     * (1+2*2-2*1*3*(1-1))*(1-2+3*(4+0));
     * 注意点:
     * 2.输入的表达书不能还有空格,括号必须匹配
     * 基本思想:
     * 1.建立操作数栈以及操作符栈
     * 2.先去括号,每次遇到')'时,就退栈,直到遇到'('
     * 3.然后处理括号中的表达式,先处理优先级高的,即*、/
     * 4.处理好高优先级操作符之后,就处理+、-这种操作符
     * 5.对以上的运算结果入栈,继续,处理完所有的(、)之后
     * 6.然后再次求一般的表达式即可
     */
    
    public class CalExpression {
    	
    	private Stack<Double > vals = new Stack<Double >();
    	private Stack<Character > ops = new Stack<Character >();
    	
    	public static void main(String[] args) {
    		CalExpression obj = new CalExpression();
    		obj.input();
    	}
    	
    	public void input() {
    		Scanner in =  new Scanner(System.in);
    		while (in.hasNext()) {
    			pushStack(in.next());
    		}
    	}
    	
    	public boolean check(char ch) {
    		if (ch == '(' || ch == ')' || ch == '+' || ch == '-'
    				|| ch == '*' || ch == '/') {
    			return true;
    		}
    		return false;
    	}
    	
    	
    	public void pushStack(String str) {
    		//匹配非数字,将(、)、+、-、*、/作为分隔符
    		String[] strNum = str.split("[^0-9]"); 
    	
    		Queue<Double > que = new LinkedList<Double >();
    		
    		for (int i = 0; i < strNum.length; ++i) {
    			if (!strNum[i].equals("")) {
    				que.offer(Double.parseDouble(strNum[i]));
    			}
    		}
    		
    		boolean flag = false;
    		for (int i = 0; i < str.length(); ++i) {
    			if (check(str.charAt(i))) {
    				//匹配到右括号,需要计算括号中的内容
    				if (str.charAt(i) == ')') {
    					Deque<Character > ops_tmp = new LinkedList<Character >();
    					while (!ops.isEmpty() && ops.peek() != '(') {
    						ops_tmp.offerFirst(ops.pop());
    					}
    					//'('退栈
    					ops.pop();
    					calExpress(ops_tmp);
    				} else {
    					ops.push(str.charAt(i));
    				}
    				flag = false;
    				
    			} else if (!flag) {
    				vals.push(que.poll());
    				flag = true;
    			}
    		}
    		
    		double value = getValue(vals.iterator(), ops.iterator());
    		
    		System.out.println(value);
    		vals.clear();
    		ops.clear();
    		
    	}
    	
    	
    	public void calExpress(Deque<Character > deq_ops) {
    		//操作数数目=操作符数目+1
    		int numCount = deq_ops.size() + 1;
    		
    		Deque<Double > deq_num = new LinkedList<Double >();
    		while (numCount > 0 && !vals.isEmpty()) {
    			deq_num.offerFirst(vals.pop());
    			numCount--;
    		}
    		
    		double value = getValue(deq_num.iterator(), deq_ops.iterator());
    		vals.push(value);
    	}
    	
    	
    	
    	public double getValue(Iterator it_num, Iterator it_ops) {
    		Deque<Double > vals = new LinkedList<Double >();
    		Deque<Character > ops = new LinkedList<Character >();
    		
    		vals.offer((double)it_num.next());
    		while (it_num.hasNext()) {
    			char ch = (char)it_ops.next();
    			if (ch == '+' || ch == '-') {
    				vals.offer((double)it_num.next());
    				ops.offer(ch);
    			} else if (ch == '*' || ch == '/') {
    				double num = vals.pollLast();
    				if (ch == '*') {
    					vals.offer(num * (double)it_num.next());
    				} else {
    					vals.offer(num / (double)it_num.next());
    				}
    			}
    		}
    		
    		double value = vals.pollFirst();
    		while (!vals.isEmpty() && !ops.isEmpty()) {
    			if ((char)ops.pollFirst() == '+') {
    				value += vals.pollFirst();
    			} else {
    				value -= vals.pollFirst();
    			}
    		}
    		
    		return value;
    	}
    
    }


  • 相关阅读:
    android 项目
    input keyevent 数字对应的操作
    logcat 使用方法
    android查看内存使用情况
    图片点击放大效果
    禁止img图片拖动在新窗口打开
    人工智能
    游戏开发
    随手做的一个模拟弹出窗口
    Html的<meta>标签使用方法及用例
  • 原文地址:https://www.cnblogs.com/wally/p/4477036.html
Copyright © 2020-2023  润新知