算式类型字符串表达式读取并计算出结果(简单四则运算)--后缀表达式计算

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);

	}

}

该方式使用了栈的数据结构具体实现看代码,有错误欢迎指出。。。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值