`
squll369
  • 浏览: 106790 次
  • 性别: Icon_minigender_1
  • 来自: 苏州
社区版块
存档分类
最新评论

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

J# 
阅读更多

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

}
  • 大小: 23.6 KB
分享到:
评论

相关推荐

    3_05 V4 (求解简单的四则运算表达式).cpp

    c++程序求解简单的四则运算表达式

    四则运算表达式求值

    按中缀形式输入一个四则运算的表达式,利用算法优选算法把其转换为后缀表达式输出,并求表达式的值。假设输入的表达式中的操作数都是1位整数。

    数据结构:栈的应用-四则算术表达式求解

    这里使用栈结构完成常见的四则算术表达式求解并对不合法的算术表达式进行判断。

    C语言课程设计-表达式求解

    表达式求解 C语言 课程设计 有源码,测试结果

    数据结构:栈的应用-算术表达式求解-后序表达式法

    将常见的中序表达式形式的四则运算算术表达式转换成电脑易于理解的后序表达式形式,并求解整个算术表达式的值。

    二叉树解决四则运算问题

    东南大学课程设计资料 include

    数据结构 表达式求值

    利用栈编写表达式求值程序:输入含有“+”、“-”、“*”、“/”四则运算的表达式,其中负数要用(0-正数)表示,并以=结束。要求输出表达式的值(两运算符号的优先关系见教材表3.1)。此题目可选做。 Input 第一...

    C#实现的表达式解析型计算器

    但限于本人水平有限,仅仅实现了基本的四则运算表达式的求解。  此外,本软件仍有许多错误、不足之处,尤其是输入表达式时,请严格按照规定的格式(详见格式说明)书写。虽然本计算器有基本的格式错误提示功能,但...

    Python实现简单的四则运算计算器

    相信大家在学习数据结构时,就学习了简单四则运算表达式求解的一个算法,可惜一直没有自己动手实现过这个算法。最近重拾数据结构与算法,恰巧又正在用Python比较频繁,所幸就用它来实现这个算法,虽然网上有很多代码...

    用栈实现算术表达式的计算

    数据结构课程作业 实现+-*/四则运算和^ 按照优先级来计算

    java递归求解带方法调用的表达式.rar

    )替换成 计算出的结果,这样表达式中就不存在 方法调用了,就成了普通的 加减乘除和括号的 四则运算的表达式了,然后使用网上普遍找到的方法求解,此工具类中只实现了 average函数,其余函数可以自己扩展

    使用z3约束求解器进行约束求解(java实现)

    内容概要: z3util可以求解含+-*/和()的约束方程的运算,例如:x=a+b*(y)+1,y=9,a!=0。可传递用“,"分割的约束表达式字符串,传入后...含括号的四则运算的计算算法。 阅读建于: 运行代码时需要配置好java的z3环境。

    数据结构c语言版.docx

    数据结构c语言版 实现顺序栈的抽象数据类型 实现顺序栈的建立、销毁、取栈顶元素、压栈、弹栈的运算 ...实现有一定通用性的程序,实现一个四则运算表达式的求解 实验代码 图片实现顺序栈的抽象数据类型

    C++表达式计算器caculator

    清华大学C++大作业 1.实数的表达式操作计算 2.大数的四则基本运算 3.数据多项式拟合,并绘制图形 4.多元线性方程组求解 5.分式多项式积分运算

    suanfa.rar_Dijkstra radix_KMP算法演示_希尔排序

    (四则表达式计算、矩阵运算、有向图的强连通分量求解) 2、算法中的链表结构和数组结构的基本操作要求单独函数实现(同组内算法要求共享使用)。 要求数据结构基本算法演示程序具有菜单选择,算法要有结果的显示...

    数据结构习题答案(全部算法)严蔚敏版

    2.2.2 向量中基本运算的实现 2.3 线性表的链表存储结构 2.3.1 单链表与指针 2.3.2 单链表的基本运算 2.4 循环链表和双向链表 2.4.1 循环链表 2.4.2 双向链表 2.4.3 顺序存储结构与链表存储结构的综合分析...

    C语言程序:模块化设计.doc

    编写多函数程序,求解两个整数的四则运算结果。 子函数个数:4个 子函数原型:int plus(int,int);int min(int,int);int as(int,int);int sdf(int,int); 子函数调用:plus(a,b);min(a,b);as(a,b);sdf(a,b); 子函数...

    《MATLAB在日常计算中的应用》【杜树春】样章

    4.1.3复数的四则运算 4.1.4复数的其他运算 4.2复数运算程序1 4.2.1复数代数形式和极坐标形式间的相互转换程序 4.2.2求代数形式复数的倒数程序 4.2.3求任一复数平方根的程序 4.2.4求两个代数形式复数之积的程序...

    各种常用算法,16个

    KMP模式匹配算法、哈夫曼编码算法、由遍历序列恢复二叉树、Prim算法、Kruskal算法、Floyd算法、Dijkstra算法、拓扑排序、关键路径算法、二叉排序树生成算法(含...(四则表达式计算、矩阵运算、有向图的强连通分量求解)

    LINGO软件的学习

    LINGO是用来求解线性和非线性优化问题的简易工具。LINGO内置了一种建立最优化模型的语言,可以简便地表达大规模问题,利用LINGO高效的求解器可快速求解并分析结果。 §1 LINGO快速入门 当你在windows下开始运行...

Global site tag (gtag.js) - Google Analytics