`
爱在爪哇
  • 浏览: 7617 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
最近访客 更多访客>>
社区版块
存档分类
最新评论

实现简单的四则混合运算

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

相关推荐

Global site tag (gtag.js) - Google Analytics