算式類型字符串表達式讀取並計算出結果(簡單四則運算)--後綴表達式計算

package com.zpl.suanfa;

import java.util.ArrayList;
import java.util.List;
import java.util.Stack;

/**
 * 用於界面簡單的四則運算字符串類型的表達式
 * 
 * @author zhangpengliang
 * 
 *         算法知識:後綴表達式 a+b*c+(d*e+f)*g
 *         <p>
 *         是正常的表達式,我們要將這個轉換成後綴表達式:abc*+de*f+g*+ <br>
 *         1、當讀到一個操作數的時候直接輸出,操作符不能立即輸出,要放到棧中,當遇到"("時也要推入到棧中<br>
 *         2、當遇到")"時,就將棧元素依次彈出,並輸出,直到彈出的符號是一個"(",就直接彈出"(",右括號就不能再推入棧中了
 *         3、當遇到其他符號如"+","*","("等時,我們從棧中彈出棧元素並輸出直到發現優先級更低的元素爲止<br>
 *         如果是同級的,比如"+"與"-"和"+"都是同級。也要彈出輸出,雖然"("的優先級很高,但是只有在處理")"纔可以彈出但不輸出
 *         4、第三步彈出輸出完後,需要將這個比較的元素壓到棧中 <br>
 *         5、如何計算abc*+de*f+g*+<br>
 *         先將a b 壓到棧中,然後遇到操作數就壓入棧中,遇到操作符就將棧中的最頂的兩位b c與操作符處理,b*c=v;然後再將v壓入 <br>
 *         棧中,依次類推
 * 
 * 
 * 
 * 
 *
 */

public class HouZhuiExpression {
	private char[] chs = { '+', '-', '*', '/', '(', ')' };

	/**
	 * 將字符串表達式轉換成一個list表,操作數與操作符分開
	 * 
	 * @param exp
	 * @return
	 */
	private List<String> expressionToHouZhuiExpression(String exp) {

		List<String> list = new ArrayList<String>();
		char[] str = exp.toCharArray();
		int j = 0;
		for (int i = 0; i < str.length; i++) {
			if (ishave(str[i])) {
				String res = exp.substring(j, i);
				j = i + 1;
				if (!res.equals("") && res != null)
					list.add(res);
				list.add(String.valueOf(str[i]));
			} else if (j < str.length && i == str.length - 1) {
				String res = exp.substring(j, i + 1);
				j = i;
				list.add(res);
			}
		}

		return list;

	}

	/**
	 * 後綴表達式
	 * 
	 * @param list
	 * @return
	 */
	private List<String> List2HouZhuiExpr(List<String> list) {
		String exp = "";
		List<String> value = new ArrayList<String>();
		Stack<String> stack = new Stack<String>();
		for (String str : list) {
			if (ishave(str)) {
				if (stack.isEmpty())
					stack.push(str);
				else {
					String a = cc(stack, str);
					exp = exp + a;
					if (!a.equals("")) {
						value.addAll(expressionToHouZhuiExpression(a));
					}

				}
			} else {
				exp = exp + str;
				value.add(str);
			}
		}
		if (!stack.isEmpty()) {
			for (int i = stack.size() - 1; i >= 0; i--) {
				exp = exp + stack.get(i);
				value.add(stack.get(i));
			}
		}
		return value;
	}

	/**
	 * 遞歸邏輯
	 * 
	 * @param stack
	 * @param str
	 * @return
	 */
	private String cc(Stack<String> stack, String str) {
		String a = "";

		if (stack.isEmpty()) {
			stack.push(str);
			return a;
		}
		String stck = stack.peek();
		if (isPop(stck, str)) {
			if (stck.equals("(")) {
				stack.pop();
				return a;
			} else {
				stack.pop();
				a = stck;
				a = a + cc(stack, str);
			}
		} else {
			stack.push(str);
		}
		return a;
	}

	/**
	 * 判斷該操作符是否要彈出
	 * 
	 * @param stck
	 * @param s
	 * @return
	 */
	private boolean isPop(String stck, String s) {
		boolean flag = false;
		if (s.equals("+") || s.equals("-")) {
			if (stck.equals("+") || stck.equals("-") || stck.equals("*") || stck.equals("/")) {
				flag = true;
			}
		} else if (s.equals("*") || s.equals("/")) {
			flag = false;
		} else if (s.equals("(")) {
			flag = false;
		} else if (s.equals(")")) {
			flag = true;
		}
		return flag;

	}

	/**
	 * 判斷字符是否爲操作符
	 * 
	 * @param ch
	 * @return
	 */
	private boolean ishave(char ch) {
		boolean flag = false;
		for (int i = 0; i < chs.length; i++) {
			if (chs[i] == ch) {
				flag = true;
				break;
			}
		}
		return flag;
	}

	/**
	 * 判斷字符串是否在這些符號中
	 * 
	 * @param ch
	 * @return
	 */
	private boolean ishave(String ch) {
		boolean flag = false;
		for (int i = 0; i < chs.length; i++) {
			if (String.valueOf(chs[i]).equals(ch)) {
				flag = true;
				break;
			}
		}
		return flag;
	}

	/**
	 * 開始計算
	 * 
	 * @param value
	 * @return
	 */
	private String caculate(List<String> value) {
		Stack<String> s = new Stack<String>();
		s.push(value.get(0));
		s.push(value.get(1));
		for (int i = 2; i < value.size(); i++) {
			String key = value.get(i);
			if (ishave(key)) {
				int a = Integer.valueOf(s.pop());
				int b = Integer.valueOf(s.pop());
				int res = sum(b, a, key);
				s.push(String.valueOf(res));
			} else {
				s.push(key);
			}
		}
		if (s.isEmpty()) {
			return "0";
		} else {
			String res = s.pop();
			return res;
		}
	}

	private int sum(int a, int b, String key) {
		if (key.equals("*")) {
			return a * b;
		} else if (key.equals("/")) {
			return a / b;
		} else if (key.equals("+")) {
			return a + b;
		} else if (key.equals("-")) {
			return a - b;
		} else
			return 0;
	}

	public static void main(String[] args) {
		HouZhuiExpression hze = new HouZhuiExpression();
		// String exp = "a+b*c+(d*e+f)*g";
		String exp = "(6/3+6*2)+9";
		List<String> list = hze.expressionToHouZhuiExpression(exp);

		List<String> b = hze.List2HouZhuiExpr(list);
		String ee = hze.caculate(b);
		System.out.println(ee);

	}

}

該方式使用了棧的數據結構具體實現看代碼,有錯誤歡迎指出。。。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章