算法练习(4)用Java实现经典栈的简单计算器

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/jinxlzc/article/details/88781897

该题目来自《算法笔记》第七章,题目编号:codeup 1918


题目描述

读入一个只包含 +, -, *, / 的非负整数计算表达式,计算该表达式的值。

输入

测试输入包含若干测试用例,每个测试用例占一行,每行不超过200个字符,整数和运算符之间用一个空格分隔。没有非法表达式。当一行中只有0时输入结束,相应的结果不要输出。

输出

对每个测试用例输出1行,即该表达式的值,精确到小数点后2位。

样例输入

30 / 90 - 26 + 97 - 5 - 6 - 13 / 88 * 6 + 51 / 29 + 79 * 87 + 57 * 92
0

样例输出

12178.21

该项目是我大二时数据结构的课程设计,完整项目有图形界面,Mybatis的CURD,在这里展示的是通过用栈和队列将算式的中缀表达式转换为后缀表达式并计算的核心代码:

package Servers;

import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;
import java.util.Stack;

public class Count 
{
	private Double thenum;
	public Double getThenum()
	{
		return thenum;
	}
	public Count(String test)
	{
		op.put('+',1);
		op.put('-',1);
		op.put('*',2);
		op.put('/',2);
		this.str=test;
		this.Change();
		this.thenum=this.Cal();
	}
	private class node
	{
		double num;  //操作数
		char op;//操作符
		boolean flag; //ture表示是操作数 false表示是操作符
	}
	private String str;
	private char[] arr;
	private  Stack<node> s=new Stack<Count.node>();
	private  LinkedList<node> q=new LinkedList<Count.node>();
	private static Map<Character, Integer> op=new HashMap<Character, Integer>();
	
	private void Change()
	{
		arr=str.toCharArray(); 
		
		
		for (int i = 0; i < arr.length;)
		{
			
			node temp=new node();
			if(arr[i]=='(')
			{
				i++;
				String son="";
				while(arr[i]!=')')
				{
					son=son+Character.toString(arr[i]);
					i++;
				}
				i++;
				temp.flag=true;
				temp.num=(new Count(son).getThenum());
				q.addLast(temp);
				continue;
			}
			if (arr[i] >= '0'&&arr[i] <= '9')//如果是数字
			{
				temp.flag = true;  //标记为数字
				temp.num = arr[i++] - '0';  //记录这个操作数的第一个数位 因为可能输入的操作数不止一位 需要一位一位合并
				while (i < arr.length && arr[i] >= '0'&&arr[i] <= '9')//若该操作数不止一位
				{
					temp.num = temp.num * 10 + (arr[i] - '0');  //更新这个操作数
					i++;
				}			
				q.addLast(temp); //将这个操作数压入表达式队列
			}
			else//如果是操作符
			{
				temp.flag = false;//标记为操作符
				while (!s.empty() && op.get(arr[i]) <= op.get(s.peek().op))
				{
					q.addLast(s.pop()); //将栈顶元素弹出到后缀表达式队列
					//操作符栈弹出元素
				}
				temp.op = arr[i];
				s.push(temp); //将该操作符压入操作符栈
				i++;
			}
		}	
		while (!s.empty())  //如果操作符栈中还有操作符 将它弹出到后缀表达式队列
		{
			q.addLast(s.pop());
		}
	}
	
	private double Cal()  //计算后缀表达式
	{
		double temp1, temp2;
		
		while (!q.isEmpty())  //后缀表达式队列非空
		{
			node cur=new node();
			node temp = new node();
			
			cur = q.getFirst();  //记录队首元素
			q.removeFirst();
			if (cur.flag == true)
			{
				s.push(cur);  //如果是数字  压入栈中
			}
			else// 如果是操作符 则要计算
			{
				temp2 = s.pop().num;  //弹出第二操作数
				temp1 = s.pop().num;  //弹出第一操作数
				temp.flag = true;  //临时记录操作数
				if (cur.op == '+') temp.num = temp1 + temp2;  //加法
				else if (cur.op == '-') temp.num = temp1 - temp2; //减法
				else if (cur.op == '*') temp.num = temp1 * temp2; //乘法
				else  temp.num = temp1 / temp2; //除法
				s.push(temp);//将操作数(结果)压入栈
			}
		}
		return s.pop().num;// while走完后栈中应仅剩一个元素  这个元素就是表达式的最终结果
	}
}

猜你喜欢

转载自blog.csdn.net/jinxlzc/article/details/88781897
今日推荐