四则运算表达式求解的简单实现

这2天比较空,就实现了一个四则运算表达式求解,记录在此,它可以计算,带刮号,带小数,正负数的求解,比如下面的算式,"5*33-(-2)*((16-(100-5.12111))-12.35)",但是没有对算式的合法性做验证,如果输入了不合法的表达式,应该会抛RuntimeException.

 

类图:

class

 

1.CaculateExpress

package com.design.study.composite;

import java.math.BigDecimal;


public abstract class CaculateExpress {
	
	protected BigDecimal value = new BigDecimal(0);

	public abstract void add(CaculateExpress s);
		
	public abstract void subtract(CaculateExpress s);
		
	public abstract void multiply(CaculateExpress s);
		
	public abstract void divide(CaculateExpress s);
	
	public String toString(){
		return value.toString();
	}
		
}

 

2.ActualCaculateExpress

package com.design.study.composite;

import java.math.BigDecimal;


public class ActualCaculateExpress extends CaculateExpress {
	
	public ActualCaculateExpress(String s1,String s2, String calExpress){
		if("+".equals(calExpress)){
			value = new BigDecimal(s1).add(new BigDecimal(s2));
		}else if("-".equals(calExpress)){
			value = new BigDecimal(s1).subtract(new BigDecimal(s2));
		}else if("*".equalsIgnoreCase(calExpress)){
			value = new BigDecimal(s1).multiply(new BigDecimal(s2));
		}else if("/".equalsIgnoreCase(calExpress)){
			value = new BigDecimal(s1).divide(new BigDecimal(s2),10,BigDecimal.ROUND_HALF_EVEN);
		}
	}

	@Override
	public void add(CaculateExpress s) {
		value = this.value.add(s.value);
	}

	@Override
	public void divide(CaculateExpress s) {
		value = this.value.divide(s.value,10,BigDecimal.ROUND_HALF_EVEN);
	}

	@Override
	public void multiply(CaculateExpress s) {
		value = this.value.multiply(s.value);
	}

	@Override
	public void subtract(CaculateExpress s) {
		value = this.value.subtract(s.value);
	}	
}

 

3.ActualCaculaterNumber

package com.design.study.composite;

import java.math.BigDecimal;


public class ActualCaculaterNumber extends CaculateExpress {
	
	@Override
	public void add(CaculateExpress s) {
		value = this.value.add(s.value);
	}

	@Override
	public void divide(CaculateExpress s) {
		value = this.value.divide(s.value,10,BigDecimal.ROUND_HALF_EVEN);
	}

	@Override
	public void multiply(CaculateExpress s) {
		value = this.value.multiply(s.value);
	}

	@Override
	public void subtract(CaculateExpress s) {
		value = this.value.subtract(s.value);
	}	
}
 

4.PackageExpress

package com.design.study.composite;

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

public class PackageExpress {
	private boolean flag = false;

	public List<String> l = new ArrayList<String>();

	public PackageExpress(String express) {
		packageExpress(express);
	}

	public void packageExpress(String s) {

		int startLoc = 0;

		if (s.startsWith("+") || s.startsWith("-")) {
			startLoc = 1;
		}
		for (int i = startLoc; i < s.length(); i++) {
			if (!flag) {
				if (checkExpressIsNumber(s)) {
					l.add(s);
					flag = true;
					return;
				}
				if ('+' == s.charAt(i) || '-' == s.charAt(i)
						|| '*' == s.charAt(i) || '/' == s.charAt(i)) {
					l.add(s.substring(0, i));
					l.add(s.substring(i, i + 1));
					s = s.substring(i + 1, s.length());
					packageExpress(s);
				}
			}
		}
	}
	
	private boolean checkExpressIsNumber(String express){
		boolean flag = true;
		
		int startLoc = 0;
		if (express.startsWith("+") || express.startsWith("-")) {
			startLoc = 1;
		}
		
		for(int i=startLoc;i<express.length();i++){
			if ('+' == express.charAt(i) || '-' == express.charAt(i) || '*' == express.charAt(i) || '/' == express.charAt(i)){
				flag = false;
			}
		}
		
		return flag;
	}
}

 

5.SubExpress

package com.design.study.composite;

public class SubExpress {
	private int startLoc;
	private int endLoc;
	private String subExpress;
	private boolean hasHuahao;
	
	public int getStartLoc() {
		return startLoc;
	}
	public void setStartLoc(int startLoc) {
		this.startLoc = startLoc;
	}
	public int getEndLoc() {
		return endLoc;
	}
	public void setEndLoc(int endLoc) {
		this.endLoc = endLoc;
	}
	public String getSubExpress() {
		return subExpress;
	}
	public void setSubExpress(String subExpress) {
		this.subExpress = subExpress;
	}
	public boolean isHasHuahao() {
		return hasHuahao;
	}
	public void setHasHuahao(boolean hasHuahao) {
		this.hasHuahao = hasHuahao;
	}
}
 

6.CaculateExpressResult

package com.design.study.composite;

import java.math.BigDecimal;
import java.util.List;

public class CaculateExpressResult extends ActualCaculaterNumber {

	public CaculateExpressResult(String v) {
		this.value = new BigDecimal(calGuaHaoExpress(v));
	}
	
	private String calGuaHaoExpress(String express){	
		SubExpress s = checkFirst(express);
		String v = calWithoutGuaHaoExpress(s.getSubExpress());
		if(s.isHasHuahao() == false){
			return v;
		}	
		
		String prvCal = null;
		if(s.getStartLoc()-2 >= 0){
			prvCal = express.substring(s.getStartLoc()-2,s.getStartLoc()-1);
		}
		String nextCal = null;
		if(s.getEndLoc()+2 <= express.length()){
			nextCal = express.substring(s.getEndLoc()+1,s.getEndLoc()+2);
		}
		
		if(prvCal != null){
			if (!"+".equals(prvCal) && !"-".equals(prvCal) && !"*".equals(prvCal) && !"/".equals(prvCal) && !"(".equals(prvCal) && !")".equals(prvCal)){
				throw new RuntimeException("Format error!");
			}
		}
		if(nextCal != null){
			if (!"+".equals(nextCal) && !"-".equals(nextCal) && !"*".equals(nextCal) && !"/".equals(nextCal) && !"(".equals(nextCal) && !")".equals(nextCal)){
				throw new RuntimeException("Format error!");
			}
		}
	
		express = express.substring(0, s.getStartLoc()-1) + v.toString() + express.substring(s.getEndLoc()+1, express.length());
		
		
		return calGuaHaoExpress(express);
	}
	
	private String calWithoutGuaHaoExpress(String express){
		List<String> l = new PackageExpress(express).l;
		l = calMulandDivExpress(l);
		l = calAddandSubExpress(l);
		return (String)l.get(0);
	}
	
	private List<String> calMulandDivExpress(List<String> l){	
		for(int i=0;i<l.size();i++){
			if("*".equals(l.get(i)) || "/".equals(l.get(i))){
				CaculateExpress s = new ActualCaculateExpress(l.get(i-1),l.get(i+1),l.get(i));
				l.remove(i-1);
				l.remove(i-1);
				l.remove(i-1);
				l.add(i-1, s.value.toString());			
				calMulandDivExpress(l);
			}
		}
		return l;
	}
	
	private List<String> calAddandSubExpress(List<String> l){	
		for(int i=0;i<l.size();i++){
			if("+".equals(l.get(i)) || "-".equals(l.get(i))){
				CaculateExpress s = new ActualCaculateExpress(l.get(i-1),l.get(i+1),l.get(i));
				l.remove(i-1);
				l.remove(i-1);
				l.remove(i-1);
				l.add(i-1, s.value.toString());		
				calAddandSubExpress(l);
			}
		}
		return l;
	}

	private SubExpress checkFirst(String s){
		int last = 0;
		int huahuaCheck = 0;
		
		for(int i=0;i<s.length();i++){
			if(')' == s.charAt(i)){
				last = i;
				huahuaCheck++;
				break;
			}
		}
		
		int prv = s.length();
		for(int j=last-1;j>=0;j--){
			if('(' == s.charAt(j)){
				prv = j;
				huahuaCheck++;
				break;
			}
		}
		
		SubExpress se = new SubExpress();
		if(huahuaCheck == 2){
			se.setHasHuahao(true);
		}else if(huahuaCheck == 0){
			se.setHasHuahao(false);
			se.setEndLoc(s.length());
			se.setStartLoc(0);
			se.setSubExpress(s);
			return se;
		}else{
			throw new RuntimeException("Format error!");
		}
			
		String t = s.substring(prv+1, last);
		se.setEndLoc(last);
		se.setStartLoc(prv+1);
		se.setSubExpress(t);
		
		return se;
	}

}

 

测试,

 

package com.design.study.composite;

public class CaculateTest {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		String express = "5*33-(-2)*((16-(100-5.12111))-12.35)";
		System.out.println(new CaculateExpressResult(express));
	}

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值