带括号的四则混合运算的算符优先算法-----java实现
1:主方法
package com.baidu;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Stack;
public class CalculateStack {
static private CalculateStack cl = new CalculateStack();
//申明一个存放数字元素的栈
private Stack<String> num = new Stack<>();
//声明一个存放操作符的栈
private Stack<Character> opStack = new Stack<>();
//申明一个优先权规则关系表
private RuleTable ruleTable = new RuleTable();
//运算简单表达式
//测试通过
//可添加运算规则
private double getCalculateNumber(double num1,Character op,double num2) {
double res = 0;
switch(op.charValue()) {
case '+':{
res = num1 + num2;
}break;
case '-':{
res = num1 - num2;
}break;
case 'x':{
res = num1 * num2;
}break;
case '/':{
res = num1 / num2;
}break;
}
return res;
}
//得到指定的俩个操作符的优先关系
/**
* @return 当返回@时为无效字符输入
* */
private char serchOp(char ch, char top) {
//System.out.println("ch:"+ch+" top:"+top);
for(Rule rule:this.ruleTable.getRuleList()) {
if(top == rule.ch1&&rule.ch2 == ch) {
//System.out.println("从表中找到:关系为top" + rule.equ +"ch");
return rule.equ;
}
}
return '@';
}
/**
* @author shilec
* 主运算算法
* @param ch1 :保存运算表达式的字符串数组
* @return Accuracy 得到运算的结果保留小数后的位数
* */
public String Calculate(String strSource,int Accuracy) {
boolean ret = true;
Object[] ch1 = this.strToOpStr(strSource);
//遍历表达式数组,逐个读入
for(int i = 0; i < ch1.length; i++) {
//判断是否是操作符
if(ch1[i].toString().isEmpty())
break;
if(!this.isOperator(ch1[i].toString())) {
//不是则如数字字符栈
this.num.push(ch1[i].toString());
}else {
//System.out.println(ch);
//从优先关系表中查找当前字符和操作符栈栈顶元素的运算优先关系
switch(this.serchOp(ch1[i].toString().charAt(0),this.opStack.lastElement())){
//如果ch优先顺序大于top 压入操作符栈
case '<':{
this.opStack.push(new Character(ch1[i].toString().charAt(0)));
//System.out.println(ch1[i].charAt(0)+"压入操作符");
}break;
//如果ch优顺序小于top 取出 俩个操作数以及弹出操作符进行运算
case '>': {
//弹出俩个数字元素
double num2 = Double.valueOf(this.num.pop());
double num1 = Double.valueOf(this.num.pop());
char op = this.opStack.pop();
//System.out.println(ch1[i].charAt(0)+"弹出操作符");
this.num.push(new Double(this.getCalculateNumber(num1, op, num2)).toString());
//但前元素不进行操作,返回重新进行比较
//栈顶元素运算,退栈
i--;
}break;
case '@': {
System.out.println("不合法的表达式");
ret = false;
}break;
case '=': {
//去括号,#号
this.opStack.pop();
//System.out.println(ch1[i].charAt(0)+"弹出操作符");
}break;
}
}
}
//格式化结果
NumberFormat nb = NumberFormat.getNumberInstance();
nb.setMinimumFractionDigits(Accuracy);
double res = Double.valueOf(this.num.pop());
return ret?nb.format(res):null;
}
/**
* 此函数用于在表达式进入运算之前检查表达式的合法性
* */
private boolean CheckeStr(String strSource) {
char[] chSource = strSource.toCharArray();
//先检查括号的数量
for(int i = 1; i < chSource.length; i++) {
if((chSource[i-1] == '('||chSource[i-1] == ')')&&!this.isOperater(chSource[i])) {
return false;
}else if((chSource[i] == '('||chSource[i] == ')')&&!this.isOperater(chSource[i-1])) {
return false;
}
}
return true;
}
//初始化俩个栈
private CalculateStack() {
//操作数栈初始化栈顶为0
this.num.push(new Integer(0).toString());
//操作符栈初始化为#(结尾符)
this.opStack.push(new Character('#'));
}
//判断字串是否为操作符
private boolean isOperator(String str) {
if(str.toCharArray().length == 1) {
for(char ch:RuleTable.op) {
if(ch == str.toCharArray()[0])
return true;
}
}else if(str.isEmpty()){
return false;
}else {
return false;
}
return false;
}
//此方法实现把操作符和操作数解析为字符串数组
private Object[] strToOpStr(String strSource) {
int num = 0;
boolean isOp = true;
String[] retStr = new String[100];
char[] ch = strSource.toCharArray();
for(char ch1:ch) {
//起始为数字
if(this.isOperater(ch1)&&num == 0&&!isOp) {
num++;
retStr[num++] = new String(new Character(ch1).toString());
isOp = true;
}else if(this.isOperater(ch1)&&num == 0&&isOp) {
//以操作符起始
retStr[num++] = new String(new Character(ch1).toString());
isOp = true;
}else if(this.isOperater(ch1)&&num != 0){
//不是起始位置并且是操作符
if(!isOp)//如果前一个不是操作符 增加num
num++;
retStr[num++] = new String(new Character(ch1).toString());
isOp = true;
}else if(!this.isOperater(ch1)&&num != 0){
//当前数字并且不是起始位置
if(retStr[num] == null)
retStr[num] = new String(new Character(ch1).toString());
else {
retStr[num] += ch1;
}
isOp = false;
}else if(!this.isOperater(ch1)&&num == 0) {
if(isOp) {
//System.out.println("opchar:" + ch1+"op:"+isOp+"num:"+num);
retStr[num] = new String(new Character(ch1).toString());
//System.out.println("opchar:" + ch1+"op:"+isOp+"num:"+num+"rerStr:"+retStr[num]);
}else {
retStr[num] += ch1;
//System.out.println("opchar:" + ch1+"op:"+isOp+"num:"+0+"rerStr:"+retStr[0]);
}
isOp = false;
}
}
ArrayList<String> list = new ArrayList<>();
for(int i = 0; i < retStr.length; i++) {
if(retStr[i] != null) {
list.add(retStr[i]);
}
}
list.add(list.size(),"#");
return list.toArray();
}
//判断一个字符是否为操作符
private boolean isOperater(char ch) {
for(char ch1:RuleTable.op) {
if(ch == ch1)
return true;
}
return false;
}
//demo
public static void main(String[] args) {
CalculateStack cl = CalculateStack.getCalculateInstance();
System.out.println(cl.Calculate("(3x4)/1.11-3x45+12-12333", 1));
}
//得到计算核心类的实例
static public CalculateStack getCalculateInstance() {
return cl;
}
}
2:算法
package com.baidu;
import java.util.ArrayList;
public class RuleTable {
//此表可添加
//操作符
static public char[] op = {
'+',
'-',
'x',
'/',
'(',
')',
'#'
};
//优先关系模拟表
//此表可添加
private int[][] re = {
{1,1,-1,-1,-1,1,1},
{1,1,-1,-1,-1,1,1},
{1,1,1,1,-1,1,1},
{1,1,1,1,-1,1,1},
{-1,-1,-1,-1,-1,0,2},
{1,1,1,1,-2,1,1},
{-1,-1,-1,-1,-1,2,0},
};
//申明一个运算优先规则列表
private ArrayList<Rule> ruleList = new ArrayList<>();
//获取运算优先规则列表
public ArrayList<Rule> getRuleList() {
return this.ruleList;
}
//生成运算优先关系表
public RuleTable() {
for(int i = 0; i < op.length; i++) {
for(int j = 0; j < op.length; j++) {
Rule rule = new Rule();
rule.ch1 = op[i];
rule.ch2 = op[j];
if(re[i][j] == 1) {
rule.equ = '>';
}else if(re[i][j] == -1) {
rule.equ = '<';
}else if(re[i][j] == 0) {
rule.equ = '=';
}else {
rule.equ = '@';
}
ruleList.add(rule);
}
}
}
//今设 第一个操作符为a 第二个为 b
//当第一个为 运算符第二个位分割符
//则运算符小于分割符
//如果第一个为分隔符第二个为运算符
//则运算符大于分隔符
}
//优先规则关系表元素
class Rule {
char ch1 = 0;
char ch2 = 0;
char equ = 0;
}
带括号的四则混合运算的算符优先算法-----java实现的更多相关文章
- 如何处理加括号的四则混合运算表达式——基于二叉树的实现(Eclipse平台 Java版)
记得上<数据结构>课程时,利用栈的特性解决过四则混合运算表达式.而如今在编写小型关系数据库的时候,编译部分要处理where后面的逻辑表达式——检查语法正确与否的同时,还要将信息传给下一个接 ...
- 用C++实现的有理数(分数)四则混合运算计算器
实现目标 用C++实现下图所示的一个console程序: 其中: 1.加减乘除四种运算符号分别用+.-.*./表示, + 和 - 还分别用于表示正号和负号. 2.分数的分子和分母以符号 / 分隔. 3 ...
- 软件工程学习之小学四则混合运算出题软件 Version 1.00 设计思路及感想
对于小学四则混合运算出题软件的设计,通过分析设计要求,我觉得为了这个软件在今后便于功能上的扩充,可以利用上学期所学习的<编译原理>一课中的LL1语法分析及制导翻译的算法来实现.这样做的好处 ...
- MathExamV2.0四则混合运算计算题生成器
MathExamV2.0四则混合运算计算题生成器----211606360 丁培晖 211606343 杨宇潇 一.预估与实际 PSP2.1 Personal Software Process Sta ...
- java 解析四则混合运算表达式并计算结果
package ch8; import java.util.LinkedList; import java.util.List; import java.util.Stack; /** * 四则混合运 ...
- C语言编程学习:写的秒速计算四则混合运算项目
C语言是面向过程的,而C++是面向对象的 C和C++的区别: C是一个结构化语言,它的重点在于算法和数据结构.C程序的设计首要考虑的是如何通过一个过程,对输入(或环境条件)进行运算处理得到输出(或实现 ...
- 软件工程学习之小学四则混合运算出题软件 Version 1.1 设计思路及感想
继上次采用形式文法来生成混合运算的算式,由于算法中没有引入控制参数而导致容易产生形式累赘(多余的括号等)的算式.本次更新决定采用一种更为简单有效的生成方式,由给出的一个随机的最终答案S,通过给定的一个 ...
- web四则混合运算3
一.程序要求: 可以控制下列参数: 是否有乘除法: 是否有括号(最多可以支持十个数参与计算): 数值范围: 加减有无负数: 除法有无余数! 二.设计思路 要求能够通过参数来控制有无乘除法,加减有无 ...
- web四则混合运算2
一.设计思路: 先出题(String型)(上周已经实现),再写方法计算结果,加入控制有无乘除法,范围,参与计算数,出题数,页码显示等简单功能,有无括号和分数的计算目前还没能实现. 二.代码: 界面 & ...
随机推荐
- nmap命令-----高级用法
探测主机存活常用方式 (1)-sP :进行ping扫描 打印出对ping扫描做出响应的主机,不做进一步测试(如端口扫描或者操作系统探测): 下面去扫描10.0.3.0/24这个网段的的主机 nmap ...
- Emmet 语法大全(缩写语法/sublime 插件)
Emmet 使用类似于 CSS 选择器的语法描述元素在生成的文档树中的位置及其属性. 元素 可以使用元素名(如 div 或者 p)来生成 HTML 标签.Emmet 没有预定义的有效元素名的集合,可以 ...
- Nginx - HTTP Configuration, the Location Block
Nginx offers you the possibility to fine-tune your configuration down to three levels — at the proto ...
- Android Wi-Fi基本操作
从用户角度看,Android Wi-Fi模块自下向上可以看为5层:硬件驱动程序,wpa_suppplicant,JNI,WiFi API,WifiSettings应用程序. 1.wpa_supplic ...
- IUSR和IIS_IUSRS
在早期的IIS版本中,随着IIS的安装,系统会创建一个IUSR_MachineName用户.IIS启用匿名访问,就是通过此用户进行身份认证的,包括FTP匿名访问,HTTP匿名访问. 在创建IUSR ...
- 牢记!SQL Server数据库开发的二十一条注意点
如果你正在负责一个基于SQL Server的项目,或者你刚刚接触SQL Server,你都有可能要面临一些数据库性能的问题,这篇文章会为你提供一些有用的指导(其中大多数也可以用于其它的DBMS). ...
- Unity User Group 北京站图文报道:《Unity3D VR游戏与应用开发》
很高兴,能有机会回报Unity技术社区:我和雨松MOMO担任UUG北京站的负责人, 组织Unity技术交流和分享活动. 本次北京UUG活动场地–微软大厦 成功的UUG离不开默默无闻的付出:提前2小时到 ...
- (转)Flickr架构
Flickr(http://www.flickr.com/ ) 是国外一个领先的图片分享网站,现在应该在yahoo门下,感觉yahoo还是有很多好东西,奈何资本要抛弃他了.这个轮回其实挺有意思的,起先 ...
- 洛古 P1373 小a和uim之大逃离
P1373 小a和uim之大逃离 题目提供者lzn 标签 动态规划 洛谷原创 难度 提高+/省选- 题目背景 小a和uim来到雨林中探险.突然一阵北风吹来,一片乌云从北部天边急涌过来,还伴着一道道闪电 ...
- NTT研发
2.研发标准 stead---大型机 css terasolunt---反向自动生成设计书 3.开发阶段做好设计,确定需求,测试阶段只是做产品有多差或者完成了多少需求,不是用来提高产品质量的过程