package Calculator;
/*
* 数学计算类
* 负责数学式子(不包含"="号)的数学运算,有运算优先级(括号最先,乘方次之,乘除再次之,加减最后等)
* 思路:按运算优先级将数学式子步步化简
* 数学式子用字符串存储,负数用中括号[]括起来表示,如:[-93]
* (测试通过)
*/
public class Calculate
{
/*
* 服务:数学运算方法--对外接口,包括本地化数学式子格式、综合加减乘除乘方和括号等运算(功能可扩展)
* 参数:要进行运算的数学式子
* 返回:运算的结果或出错提示
* (测试通过)
*/
public String calculate(String formula)
{
String result="";
formula=formula.replace(" ","");//去掉式子中的所有空格
//用小括号替换大括号
formula=formula.replace('{','(');
formula=formula.replace('}',')');
//用小括号替换中括号
formula=formula.replace('[','(');
formula=formula.replace(']',')');
result=matchRemoveBracket(formula);
if(result.startsWith("错误"))return result;
result=basicArithmetic(result);
System.out.println("原式:"+formula);
System.out.println("运算结果:"+result);
return result;
}
/*
* 服务:括号运算(包括括号匹对和去掉括号),从')'离式子开头最近的那一对括号开始
* 参数:数学式子,规定括号前后紧挨着的只能是运算符或为空而不能是数字,如:
* 87(35+3)2 错误
* (-24)^2 正确
* (23*34/(3*4)) 正确
* 4/((-64)^3) 正确
* 返回:去掉所有括号的式子或出错提示
* (测试通过)
*/
private String matchRemoveBracket(String formula)
{
System.out.println("括号运算开始!");
System.out.println("括号运算:"+formula);
if(formula.isEmpty())return "0";
if(formula.startsWith("错误"))return formula;
int left,right;
String number="";
left=formula.lastIndexOf('(');
right=formula.indexOf(')');
while(left!=-1||right!=-1)
{
if((left==-1&&right!=-1)||(left!=-1&&right==-1))
return "错误--输入错误:括号不匹配!";
if(left>right)
{
left=formula.substring(0,right).lastIndexOf('(');
if(left==-1)return "错误--输入错误:括号不匹配!";
}
if(left!=0){
//规定括号前后紧挨着的只能是运算符或为空
switch(formula.charAt(left-1))
{
case '+':case '-':case '*':case '/':case '^':case '(':break;
default:return "错误--输入错误:括号前后不能紧挨着数字!";
}
}
if(right!=formula.length()-1){
switch(formula.charAt(right+1))
{
case '+':case '-':case '*':case '/':case '^':case ')':break;
default:return "错误--输入错误:括号前后不能紧挨着数字!";
}
}
//计算括号里面的式子,在此没有括号嵌套,"从')'离式子开头最近的那一对括号开始"保证了这一点
number=basicArithmetic(formula.substring(left+1,right));
if(number.startsWith("错误"))return number;
if(number=="NaN")return "错误--运算错误!";
if(Double.parseDouble(number)>=0)//基础运算结果非负数
{
if(right==formula.length()-1)formula=formula.substring(0,left)+number;
else formula=formula.substring(0,left)+number+formula.substring(right+1);
}
else//基础运算结果为负数
{
if(right==formula.length()-1)formula=formula.substring(0,left)+"["+number+"]";
else formula=formula.substring(0,left)+"["+number+"]"+formula.substring(right+1);
}
if(formula.startsWith("错误"))return formula;
System.out.println("括号运算:"+formula);
left=formula.lastIndexOf('(');
right=formula.indexOf(')');
}
System.out.println("括号运算结束!");
return formula;
}
////////////////////////////////////////////基础运算////////////////////////////////////////////
/*
* 服务:基础运算,包括加减乘除乘方运算
* 参数:数学式子(不包含小括号)
* 返回:基础运算结果或出错提示
* (测试通过)
*/
private String basicArithmetic(String formula)
{
String result="";
result=sqrtPow(formula);
if(result.startsWith("错误"))return result;
result=multiplyDivide(result);
if(result.startsWith("错误"))return result;
result=additionSubtraction(result);
return result;
}
/*
* 服务:乘方运算(开方运算可用等价的乘方运算替代,如:√4==4^0.5)
* 参数:数学式子 -- 有乘方,加减乘除的数学式子(不包含小括号)
* 示例:
* -345+93.4^2^0.5*64+32^2/2^2+9 正确参数
* 87*(3+2)^2 错误参数
* 返回:将化简乘方之后的式子或出错提示
* (测试通过)
*/
private String sqrtPow(String formula)
{
System.out.println("乘方运算");
System.out.println("原式:"+formula);
if(formula.startsWith("错误"))return formula;
if(formula.startsWith("^")||formula.endsWith("^"))return "错误--输入错误!";
//乘方运算
for(int i=0;i<formula.length();++i)
{
if(formula.charAt(i)=='^')
{
String number="",powN="";
double num,pn;
int ai,bi;
//获得乘方的底number
if(formula.charAt(i-1)==']')//负数
{
ai=formula.substring(0,i-1).lastIndexOf('[');
if(ai==-1)return "错误--输入错误!";
number=formula.substring(ai+1,i-1);
if(ai>0)--ai;
}
else//正数
{
for(ai=i-1;ai>=0;--ai)
{
if(formula.charAt(ai)=='*'||formula.charAt(ai)=='/'
||formula.charAt(ai)=='+'||formula.charAt(ai)=='-')
{
number=formula.substring(ai+1,i);
break;
}
}
if(ai==-1)
{
number=formula.substring(0,i);
++ai;
}
}
//获得乘方的幂powN
if(formula.charAt(i+1)=='[')//负数
{
bi=formula.substring(i).indexOf(']');
if(bi==-1)return "错误--输入错误!";
bi+=i;
powN=formula.substring(i+2,bi);
++bi;
}
else
{
for(bi=i+1;bi<formula.length();++bi)
{
if(formula.charAt(bi)=='+'||formula.charAt(bi)=='-'||formula.charAt(bi)=='*'||
formula.charAt(bi)=='/'||formula.charAt(bi)=='^')
{
powN=formula.substring(i+1,bi);
break;
}
}
if(bi==formula.length())powN=formula.substring(i+1,bi);
}
System.out.println(number+" , "+powN);
try
{
num=Double.parseDouble(number);
pn=Double.parseDouble(powN);
}catch(Exception ex){
//错误包括:数字不能转换成double型等
System.out.println("错误--输入错误!");
return "错误--输入错误!";
}
try{
number=""+Math.pow(num,pn);
}catch(Exception ex){
//错误包括:数字不能转换成double型等
System.out.println("错误--运算错误!");
return "错误--运算错误!";
}
if(number=="NaN")return "错误--运算错误!";
if(Double.parseDouble(number)<0)number="["+number+"]";
if(ai==0)formula=number+formula.substring(bi);
else formula=formula.substring(0,ai+1)+number+formula.substring(bi);
System.out.println("== >"+formula);
i=ai+number.length()-1;
}
}
//System.out.println("化简乘方之后的式子:\n"+formula);
return formula;
}
/*
* 服务:乘除法运算
* 参数:数学式子 -- 只包含0-9、小数点和加减乘除号的的字符串(不包含小括号)
* 示例:-345+93.4*64+32/2+
* 返回:将化简乘除法之后的式子或出错提示
* (测试通过)
*/
private String multiplyDivide(String formula)
{
System.out.println("乘除运算");
System.out.println("原式:"+formula);
if(formula.isEmpty())return "0";
if(formula.startsWith("错误"))return formula;
//乘除号不能在式子的开头和结尾处
if(formula.startsWith("*")||formula.startsWith("/")
||formula.endsWith("*")||formula.endsWith("/"))
return "错误--输入错误:乘除号位置不对!";
String numberA=new String();
String numberB=new String();
double DA,DB;
int ai=0,bi=0;
//遍历式子,优先进行乘除法运算
for(int i=0;i<formula.length();++i)
{
if(formula.charAt(i)=='*'||formula.charAt(i)=='/')
{
//获得被乘除数numberA
if(formula.charAt(i-1)==']')//负数
{
ai=formula.substring(0,i-1).lastIndexOf('[');
if(ai==-1)return "错误--输入错误!";
numberA=formula.substring(ai+1,i-1);
if(ai>0)--ai;
}
else
{
for(ai=i-1;ai>0;--ai)
{
if(formula.charAt(ai)=='*'||formula.charAt(ai)=='/'
||formula.charAt(ai)=='+'||formula.charAt(ai)=='-')
{
numberA=formula.substring(ai+1,i);
break;
}
}
if(ai==0)numberA=formula.substri
计算器代码(有运算优先级)
3星 · 超过75%的资源 需积分: 17 69 浏览量
2013-03-18
23:27:56
上传
评论 1
收藏 5KB ZIP 举报
ligaofu
- 粉丝: 2
- 资源: 9
最新资源
- C语言基础-C语言编程基础之Leetcode编程题解之第39题组合总和.zip
- C语言基础-C语言编程基础之Leetcode编程题解之第38题外观数列.zip
- C语言基础-C语言编程基础之Leetcode编程题解之第37题解数独.zip
- C语言基础-C语言编程基础之Leetcode编程题解之第36题有效的数独.zip
- C语言基础-C语言编程基础之Leetcode编程题解之第35题搜索插入位置.zip
- index.wxml
- C语言基础-C语言编程基础之Leetcode编程题解之第33题搜索旋转排序数组.zip
- 基于Python实现的手写数字识别系统源码.zip
- 从网页提取禁止转载的文字
- C语言基础-C语言编程基础之Leetcode编程题解之第32题最长有效括号.zip
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈