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

本文介绍了一种使用栈数据结构将四则运算表达式转换为后缀表达式的方法,并实现了相应的计算功能。通过具体代码示例展示了如何处理括号、操作数和操作符。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

	}

}

该方式使用了栈的数据结构具体实现看代码,有错误欢迎指出。。。
因各个项目中需要使用根据字符串计算数值,这里写一个算法,专门计算字符串。配有大量常用公式。只有一个人方法,直接调用即可。 类名:CustomMath 函数名:Calculations(string value) 说明:求解算式表达式字符串的值 表达式中包含的符号或函数: truncate, ceiling,floor,round,log10, sign,sinh,sqrt, asin,atan,cosh, tanh, sin,cos,tan ,abs,acos, exp,log,max,min,pow,mod,+,-,*,/,',',(,) 函数说明:(不区分大小写) truncate(num) 计算指定数的整数部分 truncate(1.23)=1 ceiling (num) 返回大于或等于指定的双精度浮点数的最小整数值 ceiling(1.23)=2 floor(num) 返回小于或等于指定双精度浮点数的最大整数 floor(1.23)=1 round(num) 将双精度浮点值舍入为最接近的整数值 round(1.23)=1 round(num,num1) 将小数值按指定的小数位数舍入 round(1.23,1)=1.2 log10(num) 返回指定数字以 10 为底的对数 log10(10)=1 sign(num) 返回表示数字符号的值 sign(1.23)=1 sinh(num) 返回指定角度的双曲正弦值 sinh(1.23)=1.5644 sqrt(num) 返回指定数字的平方根 sqrt(9)=3 sqrt(num,num1) 返回指定数字的num1根 sqrt(27,3)=3 asin(num) 返回正弦值为指定数字的角度 asin(0.5)=PI/6 atan(num) 返回正切值为指定数字的角度 atan(1)=45 cosh(num) 返回指定角度的双曲余弦值 cosh(1.23)=1.8567 tanh(num) 返回指定角度的双曲正切值 tanh(1.23)=0.8425 sin(num) 返回指定角度的正弦值 sin(PI/6)=0.5 cos(num) 返回指定角度的余弦值 sin(PI/3)=0.5 tan(num) 返回指定角度的余切值 sin(PI/4)=1 abs(num) 返回数字的绝对值 abs(-12)=12 acos(num) 返回余弦值为指定数字的角度 acos(0.5)=PI/3 exp(num) 返回 e 的指定次幂 exp(1)=2.718 log(num) 返回指定数字的自然对数(底为 e) log(e)=1 log(num,num1) 返回指定数字在使用指定底时的对数 log(e,e)=1 max(num,um1) 返回最大值 max(1,2)=2 min(num,num1) 返回最小值 min(1,2)=1 pow(num,num1) 返回指定数字的指定次幂 pow(2,2)=4 mod(num,num1) 返回余数 mod(3,2)=1 常量: PI 值:3.14159265358979323846 E 值:2.7182818284590452354 YEAR 值:当前年份 MONTH 值:当前月份 DAY 值: 当前日 HOUR 值:当前时 MINUTE 值:当前分 SECOND 值:当前秒 RANDOM 值:一个随机数(0-1 之间) 实例 系统计算:1+2*3/4-0.5=2 函数计算:1+2*3/4-0.5=2 调用方式:CustomMath.Calculations("1+2*3/4-0.5") 系统计算(1+2)*3/4-0.5=1.75 函数计算(1+2)*3/4-0.5=1.75 调用方式:CustomMath.Calculations("(1+2)*3/4-0.5") 系统计算(sin(pi)+sqrt(3+5*7+(2+8/4*5+2)))/6=1.20185042515466 公式计算(sin(pi)+sqrt(3+5*7+(2+8/4*5+2)))/6=1.20185042515466 调用方式:CustomMath.Calculations("(sin(pi)+sqrt(3+5*7+(2+8/4*5+2)))/6") 系统计算:sin(pow(3,2)/4)+3.5-9*sqrt(81)=-76.7219268031121 函数计算:sin(pow(3,2)/4)+3.5-9*sqrt(81)=-76.7219268031121 调用方式:CustomMath.Calculations("sin(pow(3,2)/4)+3.5-9*sqrt(81)")
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值