实现简单的四则混合运算
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 stubString 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;如果当前运行级别大于当前,则对当前操作符进行分析,根据当前运算符性质及当前操作数得出结果入操作数栈;如果当前操作符的优先级小于当前操作符栈顶优先级,则对当前操作符进行操作运算,将结果入操作数栈,然后将这个较小优先级的操作符入操作符栈;直至终结解析完所有的操作符,操作符栈为空,这个时候运算完毕,操作数栈顶元素即为表达式运算结果。