尧图精选

java实现一个包含四则运算和小括号的计算器

🕒 发布时间:2026/10/2 17:31:50 📁 来源:尧图网络
写了一个包含四则运算和小括号的类可以输入一个长串的算式根据四则运算和小括号的运算顺序计算出最终值并按照脱式计算格式打印步骤输入: 1-(- (2*5)/-2)9×3 输出 1-(-(2×5)÷-2)9×3 1-(-(2×5)÷-2)9×3 1-(10÷2)9×3 1-59×3 1-527 -427 23最终代码importjava.util.ArrayList;importjava.util.List;importjava.util.regex.Pattern;publicclassComputor{privatestaticfinalStringLEFT_BRACKET(;privatestaticfinalStringRIGHT_BRACKET);privatestaticfinalStringADD;privatestaticfinalStringSUB-;privatestaticfinalStringMUL×;privatestaticfinalStringDIV÷;privatefinalListStringlistnewArrayList();publicvoidinputFormula(Stringformula){try{//将计算机运算符改成数学运算符把中文括号改成英文括号把空格去掉formulaformula.replace(*,MUL).replace(/,DIV).replace(,LEFT_BRACKET).replace(,RIGHT_BRACKET).replaceAll(\\s*,);list.add(formula);//先把运算符连用的情况改善一下StringtoChangeopChange(formula);if(!toChange.equals(formula)){printLog(true,toChange);}//开始计算bracketComputer(formula,true);//打印运算步骤for(Stringstep:list){System.out.println(step);}}catch(Exceptione){System.err.println(计算出错);}}//将小括号拆出来再做四则运算privateStringbracketComputer(Stringformula,booleanisLog){//算式中若是没有括号就按照四则运算法则开始计算if(!formula.contains(RIGHT_BRACKET)){returnfourRulesComputer(formula,isLog);}//先从左边找到第一个右括号再从这个右括号往左找左括号这样就能找到最里层的一对括号以及括号包含的式子intrightBracketIndexformula.indexOf(RIGHT_BRACKET);intleftBracketIndexformula.lastIndexOf(LEFT_BRACKET,rightBracketIndex);StringunitFormulaformula.substring(leftBracketIndex,rightBracketIndex1);//找到的式子两边还包含了一对括号应当去除。然后再按照四则运算法则开始运算StringdelBracketunitFormula.substring(1,unitFormula.length()-1);StringunitResultfourRulesComputer(delBracket,false);//把运算结果与替换现在的这个括号里的内容组成一个新的公式这样就减少了一对括号unitResultformula.replace(unitFormula,unitResult);//记录一下这个式子的运算之后的式子相当于做一个脱式计算printLog(isLog,opChange(unitResult));//一个公式可能不止一对括号所以还需要直接递归查找是否有下一对括号returnbracketComputer(unitResult,isLog);}//四则运算privateStringfourRulesComputer(Stringformula,booleanisLog){formulaopChange(formula);//根据四则运算法则从左往右查找应优先运算的运算符如果没有获取到运算符则认为公式只剩一个数字即只剩运算结果StringopgetOperation(formula);if(op.isEmpty())returnformula;//查找运算符的所在位置及其两边参与运算的数据组成最小的运算步骤。//从下标1开始找是因为可能当formula-1-2从下标1开始找就可以略过左边那个负号intopIndexformula.indexOf(op,1);StringleftNumsearchNum(formula,opIndex,-1);StringrightNumsearchNum(formula,opIndex,1);//运算结果StringunitResultcomputer(leftNum,op,rightNum);//记录下当前步骤运算完成后的公式StringunitFormulaleftNumoprightNum;printLog(isLog,formula.replace(unitFormula,unitResult));//算完一步之后继续递归算下一步骤returnfourRulesComputer(formula.replace(unitFormula,unitResult),isLog);}//把连续出现的两个运算符根据负负得正法则变成一个privateStringopChange(Stringformula){StringmulSubMULSUB;StringdivSubDIVSUB;StringaddSubADDSUB;StringsubSubSUBSUB;StringmulAddMULADD;StringdivAddDIVADD;StringbracketAddLEFT_BRACKETADD;Stringchangeformula;if(formula.contains(mulSub)){//如果出现×-就把-移到运算符左边那个数的前面intopIndexformula.lastIndexOf(mulSub);StringleftNumsearchNum(formula,opIndex,-1);changeformula.replace(leftNummulSub,SUBleftNumMUL);}elseif(formula.contains(divSub)){//如果出现÷-就把-移到运算符左边那个数的前面intopIndexformula.lastIndexOf(divSub);StringleftNumsearchNum(formula,opIndex,-1);changeformula.replace(leftNumdivSub,SUBleftNumDIV);}elseif(formula.contains(addSub)){//把-变成-changeformula.replace(addSub,SUB);}elseif(formula.contains(subSub)){//把--变成changeformula.replaceFirst(subSub,ADD);}elseif(formula.contains(mulAdd)){//把×变成×。被替换的字体需要转义一下否则会被当做正则表达式使用changeformula.replaceFirst(MUL\\ADD,MUL);}elseif(formula.contains(divAdd)){//把÷变成÷。被替换的字体需要转义一下否则会被当做正则表达式使用changeformula.replaceFirst(DIV\\ADD,DIV);}elseif(formula.contains(bracketAdd)){//把(变成(。被替换的字体需要转义一下否则会被当做正则表达式使用changeformula.replaceFirst(\\LEFT_BRACKET\\,LEFT_BRACKET);}elseif(formula.startsWith()){//用正则把算式最前面的移除changechange.substring(1);}else{//返回合适的算式returnchange;}returnopChange(change);}//根据运算符的下标寻找运算符左右两边的数字direction -1查找左边的数字direction 1查找右边的数字privateStringsearchNum(Stringformula,intstartIndex,intdirection){if(direction-1){//找运算符号左边的数字for(intistartIndexdirection;i0;i--){Stringnumformula.substring(i,startIndex);//遇到其它的运算符号就相当于找全了这个数字if(isNonNum(num)){//可能算式的第一个数字还包含了负号查找数字的时候是不能把负号给落下的if(i0formula.charAt(i)-){returnnum;}else{returnnum.substring(1);}}}//遍历完字符串都没找到符号说明左边没有其它的运算符了returnformula.substring(0,startIndex);}else{//找运算符号右边的数字startIndex;for(intistartIndexdirection;iformula.length();i){Stringnumformula.substring(startIndex,i);//遇到其它的运算符号就相当于找全了这个数字可以直接返回了if(isNonNum(num)){returnnum.substring(0,num.length()-1);}}//遍历完字符串都没找到符号说明右边没有其它的运算符了returnformula.substring(startIndex);}}//获取此步需要执行的运算符有乘除的要先算乘除乘除都有则从左往右算否则算加减加减若也都有也是从左往右算privateStringgetOperation(Stringformula){if(formula.contains(MUL)||formula.contains(DIV)){intmulIndexformula.indexOf(MUL);intdivIndexformula.indexOf(DIV);if(mulIndex-1divIndex0){returnDIV;}elseif(mulIndex0divIndex-1){returnMUL;}else{returnmulIndexdivIndex?MUL:DIV;}}elseif(formula.indexOf(ADD,1)0||formula.indexOf(SUB,1)0){//略过算式最左边可能是负号的情况intaddIndexformula.indexOf(ADD,1);intsubIndexformula.indexOf(SUB,1);if(addIndex-1subIndex0){returnSUB;}elseif(addIndex0subIndex-1){returnADD;}else{returnaddIndexsubIndex?ADD:SUB;}}return;}//根据运算符把两个数进行运算privateStringcomputer(Stringleft,Stringop,Stringright){if(left.isEmpty())returnopright;floatleftNumFloat.parseFloat(left);floatrightNumFloat.parseFloat(right);floatresultswitch(op){caseMUL-leftNum*rightNum;caseDIV-leftNum/rightNum;caseADD-leftNumrightNum;caseSUB-leftNum-rightNum;default-0;};returnstripTrailingZeros(result);}//判断是不是数字privatebooleanisNonNum(Stringformula){PatternpatternPattern.compile([0123456789.]*);return!pattern.matcher(formula).matches();}//去除小数点后面多余的0privateStringstripTrailingZeros(Stringnum){returnnum.replaceAll(0$,).replaceAll(\\.$,);}//记录运算过程privatevoidprintLog(booleanisLog,Stringlog){if(isLog){list.add(log);}}}
上一篇/下一篇内容由系统自动关联 返回资讯列表 →