java 逆波兰表达式 (后缀表达式) 计算器

   在写计算器应用程序时,我们需要通过四则运算表达式构造逆波兰表达式,通过逆波兰表达式进行求值。

   <注:逆波兰表达式,也称后缀表达式>

  

  算法:需要构造运算符栈,通过进栈、出栈将愿表达式转换成为所需的逆波兰表达式。

              转换过程:

                           (1)从左到右,依次读入,若读入字符是数字,则将其输出到逆波兰表达式列表。

                            (2)若读入字符是  '(' , 直接入栈;

                                      若是 ‘)’,则采取出栈操作并顺序输出,直到 遇到第一个‘(‘ , ’(‘出栈不输出;

                              (3)若为其他运算符,则比较 栈顶元素 与 该优先符 优先级;

                                                    当栈顶元素优先级 >= 当前元素优先级,出栈并顺序输出栈内运算符,直到栈顶元素优先 

                                                     级 <  当前元素优先级,将当前的运算符入栈。

                                        若当前运算符优先级 >  栈顶运算符优先级, 直接入栈即可。

                               (4)扫描结束,顺序输出栈内元素,添至逆波兰表达式列表尾处即可。


 附带实现代码:

                基本定义:

	private final static String OPER1 = "+";
	private final static String OPER2 = "-";
	private final static String OPER3 = "*";
	private final static String OPER4 = "/";        
	private final static String OPERLEF = "(";
	private final static String OPERRIGHT = ")";
	private String exp; 
	private int precision = 4;             // 精度计算
	private RoundingMode roundingmode = RoundingMode.HALF_UP;
	private List<String> expList = new ArrayList<String>(); 
	private List<String> postfixList = new ArrayList<String>();
  

               栈的定义,不解释,见代码;

               

        private class Stack
	{
		LinkedList<String> stackList = new LinkedList<String>();
		public Stack()
		{}
			
		public boolean isEmpty()
		{
			return stackList.isEmpty();
		}
		public void push(String expession)
		{
			stackList.addLast(expession);
		}
		
		public String pop()
		{
			return stackList.removeLast();
		}	
		
		public String top()
		{
			return stackList.getLast();
		}
	}
                依次为判断是否是 ’)‘ ,’(‘,数字,以及优先级高低:

            

public boolean isNum(String str)
	{
		return str.startsWith("0")||
				str.startsWith("1")||
				str.startsWith("2")||
				str.startsWith("3")||
				str.startsWith("4")||
				str.startsWith("5")||
				str.startsWith("6")||
				str.startsWith("7")||
				str.startsWith("8")||
				str.startsWith("9")||
				str.startsWith(".");
	}
	
	/**The method using for judge whether 
	 * a char is a 'x' or a '/'
	 * */
	
	private boolean isHigher(String str)
	{
		if(str.equals(OPER3)||str.equals(OPER4))
		{
			return true;
		}
		else
		{
			return false;
		}
	}
	
	/** The method using for judge whether the 
	 * priority if str1 is higher than the str2
	 * */
	
	private boolean compare(String str1, String str2)
	{
		if(str1.equals(OPERLEF))
		{
			return false;
		}
		if((!isHigher(str1))&&(isHigher(str2)))
		{
			return false;
		}
		else
		{
			if(isHigher(str1))
			{
				return true;
			}
			else
			{
				return false;
			}
		}
	}
	
	/** The method using for judge the 
	 * '('*/
	
	private boolean isLeft(String str)
	{
		return str.equals(OPERLEF);
	}
	
	/**The method using for judge the 
	 * ')'*/
	private boolean isRight(String str)
	{
		return str.equals(OPERRIGHT);
	}
  

                实现 四则运算的数字与运算符的分离,放入字符串内,后转换成后缀表达式,之后对后缀表达式进行计算。

     

private void seperate()
	{
		int length = exp.length();
		String tempStr = "";
		for(int i = 0; i < length; i++)
		{
			String tempChar = exp.substring(i,i+1);
			if(isNum(tempChar))
			{
				tempStr += tempChar;
			}
			else
			{
				if(!tempStr.equals(""))
				{
					expList.add(tempStr);
				}
				expList.add(tempChar);
				tempStr = "";
			}
		}
		if(!tempStr.equals(""))
		{
			expList.add(tempStr);
		}
	}
	
	/** The method using the expression list to 
	 * convert a poxfixExpression
	 * return a poxfixList
	 * */
	
	private void convertPoxfix()
	{
		Stack stack = new Stack();
		int length = expList.size();
		for(int i= 0; i < length; i++)
		{
			String ch = expList.get(i);
			if(isNum(ch))
			{
				postfixList.add(ch);
			}
			else
			{
				if(isLeft(ch))
				{
					stack.push(ch);
				}
				else 
					if(isRight(ch))
					{
						while(!stack.isEmpty())
						{
							String tempChar = stack.pop();
							if(!tempChar.equals(OPERLEF))
							{
								postfixList.add(tempChar);
							}
							else
							{
								break;
							}
						}
					}
					else
					{
						if(stack.isEmpty())
						{
							stack.push(ch);
						}
						else
						{
							if(compare(stack.top(),ch))
							{
								while(!stack.isEmpty() && compare(stack.top(),ch))
							     	{
									postfixList.add(stack.pop());
									}
							}
							stack.push(ch);
						}
						
					}
			}		
		}
		while(!stack.isEmpty())
		{
			postfixList.add(stack.pop());
		}
	}
	
	/**The method using for the calculation on the decimal precision
	 * */
	public static BigDecimal getBigDecimal(String numString, int precision, RoundingMode roundingmode)
	{
		String precisionFlag = "0";
		if(numString == null || numString.equals(""))
		{
			precisionFlag = "0.00";
		}
		else
		{
			precisionFlag = numString;
		}
		
		BigDecimal bigdecimal = new BigDecimal(precisionFlag);
		bigdecimal.setScale(precision, roundingmode);
		return bigdecimal;
	}
	
	/**the method which uses the postifixExpression to calculate
	 * the expression 
	 * return the answer which is on the top of the stack
	 * */
	
	public String calculation() throws ArithmeticException
	{
		Stack numStack = new Stack();
		int length = postfixList.size();
		for(int i = 0; i < length; i++)
		{
			String tempC = postfixList.get(i);
			
			if(isNum(tempC))
			{
				numStack.push(tempC);
			}
			else
			{
				BigDecimal tempNum1 = getBigDecimal(numStack.pop(),precision,roundingmode);
				BigDecimal tempNum2 = getBigDecimal(numStack.pop(),precision,roundingmode);
				BigDecimal tempNum = getBigDecimal("",precision,roundingmode);
				
				if(tempC.equals(OPER1))
				{
					tempNum = tempNum2.add(tempNum1);
				}
				else
					if(tempC.equals(OPER2))
					{
						tempNum = tempNum2.subtract(tempNum1);
					}
					else
						if(tempC.equals(OPER3))
						{
							tempNum = tempNum2.multiply(tempNum1);
						}
						else
							if(tempC.equals(OPER4))
							{
								tempNum = tempNum2.divide(tempNum1, precision, roundingmode);
							}
				numStack.push(tempNum.toString());
			}
		}
		return numStack.pop();
	}
              类的构造:

public PostfixExp(String exp, int precision, RoundingMode roundingmode)
	{
		this.exp = exp;
		this.precision = precision;
		this.roundingmode = roundingmode;
		seperate();
		convertPoxfix();
		
	}

          测试代码:

public String getPostfix()
	{
		String post = "";
		int length = postfixList.size();
		for(int i = 0; i < length; i++)
		{
			post += postfixList.get(i)+" ";
		}
		return post;
	}

public static void main(String[] args)
	{
		String str = "1+4/2*3+5+(3+1)+2/2";
		System.out.println("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
		PostfixExp postfixexp = new PostfixExp(str,10,RoundingMode.HALF_UP);
		String post = postfixexp.getPostfix();
		System.out.println("PostFix Expression: "+ post);
		System.out.println("Answer : "+ postfixexp.calculation());
	}

     至此  所有源代码已经给出,欢迎批评指正!!

      部分思想源于网上大牛! 多谢各位大牛指导!!!



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值