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();
}
}