兑现简单的四则混合运算
实现简单的四则混合运算
package cn.gao.algorithm2.service; import java.util.ArrayList; /** * 四则混合运算运算,如给定一个字符串"a+b*c-d/e",计算该表达式值 * @param args */ public class Test11 { public ArrayList<Integer> objectList;/*保存操作数数组*/ public ArrayList<Integer> operatorList;/*保存操作符数组*/ public String s;/*保存四则运算表达式字符串*/ public Test11(String s) {/*四则运算表达式测试类构造器*/ super(); this.s = s; objectList=new ArrayList<Integer>(); operatorList=new ArrayList<Integer>(); } public void prase()/*解析四则运算表达式字符串,将解析后的操作数及操作符分别保存在objectList和operatorList中*/ { System.out.println("表达式为:"+s); int index=0; int object; int operatorIndex; while(index<=s.length()-1) { operatorIndex=getNextOperator(index); //System.out.println("sssssssss:"+operatorIndex); if(operatorIndex==-1) { object=getNumberWithRange(index,s.length()); objectList.add(object); break ; } else{ object=getNumberWithRange(index,operatorIndex); objectList.add(object); operatorList.add(Integer.valueOf(s.charAt(operatorIndex))); index=operatorIndex+1; } } System.out.println("解析后的操作数: "+objectList); System.out.println("解析后的操作符: "+operatorList); } public void caculate()/*根据已有的objectList和operatorList来就算表达式的值*/ { ArrayList<Integer> objectList2=new ArrayList<Integer>();/*中间态操作数容器*/ ArrayList<Integer> operatorList2=new ArrayList<Integer>();/*中间态操作符容器*/ boolean flag=false;/*中间态状态辅助标志,标志上一次运算是优先级高的运算*/ /*以下for循环是将objectList与operatorList里面的东西经过一次高级运算后过滤,将操作数及低级运算保存便于后续计算*/ for(int i=0,j=0;i<objectList.size()&&j<operatorList.size();i++,j++)/*i,j分别指向当前操作数容器指针和当前操作符指针*/ { int opertator=operatorList.get(j); int object=objectList.get(i); if(opertator=='*'||opertator=='/')/*处理优先级较高的运算*/ { int one=objectList.get(i); int second=objectList.get(i+1); int result=getResultByOperator(one,second,opertator); if(result!=-1) { if(!flag)/*上次操作是普通优先级的*/ { objectList2.add(result); } else{ objectList2.remove(objectList2.size()-1);/*移除上次高优先级存的值*/ objectList2.add(result);/*将二次高优先级的值存入*/ } objectList.set(i+1, result); flag=true; } } else{ if(!flag) { objectList2.add(object); } operatorList2.add(opertator); flag=false; } } System.out.println("aaaaaa: "+objectList2); System.out.println("bbbbb: "+operatorList2); /*以下结算结果值*/ int i; for(i=0;i<operatorList2.size();i++) { int one=objectList2.get(i); int second=objectList2.get(i+1); int operator=operatorList2.get(i); objectList2.set(i+1, getResultByOperator(one,second,operator)); } System.out.println("表达式计算结果的值为:"+objectList2.get(i)); } public int getResultByOperator(int one,int second,int operator)/*二目运算函数的抽象,根据制定的操作符及操作数得出结果返回*/ { if(operator=='+') { return one+second; } if(operator=='-') { return one-second; } if(operator=='*') { return one*second; } if(operator=='/') { return one/second; } return -1; } public int getNumberWithRange(int startIndex,int endIndex)/*根据开头索引和结尾索引获得对应的整数值*/ { return Integer.parseInt(s.substring(startIndex, endIndex)); } public int getNextOperator(int index)/*获取字符串当前index的下一个最近的操作符索引*/ { if(index>=s.length()-1) { return -1; } while(index<=s.length()-1) { if(isOperator(index)) { //System.out.println("获得当前操作索引符:"+s.charAt(index)+"索引位置:"+index); return index; } index++; } return -1; } public boolean isOperator(int index)/*判断当前索引操作数是否属于操作符*/ { int temp=s.charAt(index); if('+'==temp||'-'==temp||'*'==temp||'/'==temp) { return true; } return false; } public static void main(String[] args) { // TODO Auto-generated method stub String s="1+2*3-8/4*2*2"; Test11 t=new Test11(s); t.prase(); t.caculate(); } }
1 楼
爱在爪哇
2012-05-27
这里只是做了粗糙的四则运算处理,实际不止+ - * /这些运算符,可能对应不同级别S1,S2,...级别的运算符(这里只有二个运行级别:+,-以及*,/),以及不固定的操作符(这里都只是二目操作符),可以将以上问题抽象,然后精确处理思路如下:
设计2个栈,一个保存操作数的栈K1,一个保存操作符的栈K2,不断的解析表达式,进行词法分析,遇到和当前操作符栈同级别的操作符,则将当前操作符入K2,操作数入K1;如果当前运行级别大于当前,则对当前操作符进行分析,根据当前运算符性质及当前操作数得出结果入操作数栈;如果当前操作符的优先级小于当前操作符栈顶优先级,则对当前操作符进行操作运算,将结果入操作数栈,然后将这个较小优先级的操作符入操作符栈;直至终结解析完所有的操作符,操作符栈为空,这个时候运算完毕,操作数栈顶元素即为表达式运算结果。
设计2个栈,一个保存操作数的栈K1,一个保存操作符的栈K2,不断的解析表达式,进行词法分析,遇到和当前操作符栈同级别的操作符,则将当前操作符入K2,操作数入K1;如果当前运行级别大于当前,则对当前操作符进行分析,根据当前运算符性质及当前操作数得出结果入操作数栈;如果当前操作符的优先级小于当前操作符栈顶优先级,则对当前操作符进行操作运算,将结果入操作数栈,然后将这个较小优先级的操作符入操作符栈;直至终结解析完所有的操作符,操作符栈为空,这个时候运算完毕,操作数栈顶元素即为表达式运算结果。