Java栈操作-综合计算器(中缀表达式+后缀表达式)

第一部分,仅实现简单计算功能,复杂运算会在后续完善。仅实现像3+5*9-2+7这样的运算。

2021.4.14更新,第二部分:后缀表达式可完成多位数及括号运算

预告,中缀表达式转后缀表达式

思路

来源于尚硅谷课堂
来源于尚硅谷网课

2021.4.11修改,可以计算多位数,并修改了一个小Bug

package Stack;

public class computstack {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		/*包含功能(public)
		 * 1.构造器
		 * 2.判断栈空
		 * 3.判断栈满
		 * 4.遍历栈
		 * 5.入栈
		 * 6.出栈
		 * 7.判断符号优先级
		 * 8.判断读取元素是数字还是字符
		 * 9.计算相操作结果
		 * 10.显示栈顶元素(计算时调用)
		 * */
		//测试
		//创建数字栈和符号栈,分别存放数字和字符
		ArrayComputStackLinked numstack = new ArrayComputStackLinked(10);
		ArrayComputStackLinked chstack = new ArrayComputStackLinked(10);
		//定义字符串并定义辅助指针遍历
		String expression = "20-10+5*4";//30
		//定义相关变量
		int num1 = 0;	//算数1
		int num2 = 0;	//算数2
		int ch;		//操作符
		int index = 0;	//辅助指针
		int res = 0;	//运算结果
		char chch = ' ';//暂存运算符
		String sumnums = "";//连接多位数
		//开始扫描字符串将结果分别导入两个栈中
		while(true) {
			//取出一位且步长为1,构成字符串,然后取出字符串的第0位
			chch = expression.substring(index,index+1).charAt(0);//[0,1)
			//取出chch后判断什么形式
			if(chstack.judge(chch)) {
				//若为字符串
				if(!chstack.emptystack()) {
					//若符号栈不为空,比较与栈中字符的优先级,若优先级高则直接入栈,若优先级第则取出原先的字符参与运算,最后入栈
					if(chstack.priority(chch)>chstack.priority(chstack.peek())) {
						//优先级较高,直接入栈
						chstack.push(chch);
						
					}else {
						//优先级较低,出栈一位运算
						num1 = numstack.pop();//出一位数字
						num2 = numstack.pop();//出一位数字
						ch = chstack.pop();	//出一位符号
						res = numstack.operation(num1,num2,ch);
						numstack.push(res);
						chstack.push(chch);
					}
				}else {
					//栈为空
					chstack.push(chch);
				}
			}else {
				//取出元素为数字
				//numstack.push(chch-'0');//chch-48	
				//判断数字位数并取出存入数栈
				sumnums+=chch;
				if(index == expression.length()-1) {
					numstack.push(Integer.parseInt(sumnums));//最后一位时数字入数栈
				}else {
					if(chstack.judge(expression.substring(index+1,index+2).charAt(0))) {//???
						//若元素的后一位时字符,则可以入数栈
						numstack.push(Integer.parseInt(sumnums));//合并好的数字入数栈
						sumnums = "";//清空,为下次做准备
					}
				}
			}
			index++;
		if(index >=expression.length()) {
			break;
		}
		
	}
		//遍历完毕,剩余元素运算后入数栈
		while(true) {
			if(chstack.emptystack()) {
				break;//字符栈为空表示运算完毕,数栈中为结果
			}else {
				num1 = numstack.pop();
				num2 = numstack.pop();
				ch = chstack.pop();
				res = numstack.operation(num1,num2,ch);
				numstack.push(res);
			}
		}
		//结束后数栈只剩结果
		System.out.printf("表达式%s的运算结果为%d\n",expression,numstack.peek());//numstack.pop()
	}
}

class ArrayComputStackLinked{
	private int top = -1;	//栈顶
	private int[]stack;	//定义数组栈
	private int MaxTop;	//定义栈的大小
	
	//创建构造器
	public ArrayComputStackLinked(int maxtop) {
		this.MaxTop = maxtop;	//传入栈的大小
		stack = new int[this.MaxTop];	//创建栈,大小等于输入
	}
	
	/*开始创建操作函数*/
	//判断栈空
	public boolean emptystack() {
		return top == -1;
	}
	//判断栈满
	public boolean isfullstack() {
		return top == MaxTop-1;	//???
	}
	//遍历栈
	public void liststack() {
		//考虑栈空时无法遍历
		if(emptystack()) {
			System.out.println("栈空,无法遍历");
			return;
		}
		//栈中数值正常时
		for(int i = top;i>=0;i--) {
			System.out.printf("stack[%d] = %d\n",i,stack[i]);
		}
	}
	//入栈操作
	public void push(int value) {
		//判断栈是否满
		if(isfullstack()) {
			System.out.println("栈满,无法入栈");
			return;
		}
		//栈不满时
		top++;
		stack[top] = value;
	}

	//出栈
	public int pop() {
		//栈空
		if(emptystack()) {
//			System.out.println("栈空,无法出栈");
//			return 0;
			//抛出异常
			throw new RuntimeException("栈空,没有数据");
		}
		//栈非空时
		int value = stack[top];
		top--;
		return value;
	}
	
	//定义功能:判断符号优先级
	public int priority(int ch) {
		if(ch == '*' || ch == '/') {
			return 1;
		}else if(ch == '+' || ch == '-') {
			return 0;
		}else {
			return -1;
		}
	}
	
	//定义功能判断指向的是数字还是字符:利用布尔变量
	public boolean judge(char ch) {
		return ch == '-' || ch=='+' || ch =='*' || ch =='/';
		//出现符号时返回真值
	}
	
	//运算模块:完成符号+数字运算(数字1,数字2,运算字符)
	public int operation(int num1,int num2,int ch) {	//int和cahr通用
		int num = 0;//暂存运算结果
		switch(ch) {
		case '+':
			num = num1+num2;
			break;
		case '-':
			num = num2-num1;//num2为后出先进数字
			break;
		case '*':
			num = num1*num2;
			break;
		case '/':
			num = num2/num1;
			break;
		default:
			break;
		}
		//最后返回运算结果
		return num;
	}
	
	//显示栈顶元素(不取出)
	public int peek() {
		return stack[top];
	}
	
}

利用逆波兰表达式计算

package Poland;

import java.util.List;
import java.util.Stack;
import java.util.ArrayList;
public class Polandcomputer {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		/*逆波兰表达式计算器
		 * 后缀表达式:34+5*6-
		 * 中缀表达式:(3+4)*5-6
		 * 思路:将中缀表达式转化为后缀表达式,然后读取进list集合中
		 * 最后从list中读取元素并计算
		 * */
		String Postfixexpression = "30 4 + 5 * 6 -";//创建字符串
		List<String> rpnList = getListString(Postfixexpression);
		System.out.println("rpnList" + rpnList);
		int result = computer(rpnList);
		System.out.println("计算结果="+result);
		
	}
	
	//将逆波兰表达式一次读入数组中ArrayList
	public static List<String> getListString(String Postfixexpression){//定义方法,输入字符串
		//将Postfixexpression分割
		String[] split = Postfixexpression.split(" ");//返回一个数组
		//System.out.println(split);
		List<String> list = new ArrayList<String>();//创建新列表list
		for(String ele:split) {//for循环增强
			list.add(ele);
		}
		return list;
	}
	
	public static int computer(List<String> ch) {
		//创建栈
		Stack<String> stack = new Stack<String>();
		//遍历ch
		for(String item:ch) {
			//正则表达式取出数
			if(item.matches("\\d+")) {//匹配多位数
				stack.push(item);
			}else {
				int num2 = Integer.parseInt(stack.pop());
				int num1 = Integer.parseInt(stack.pop());
				int result = 0;
				if(item.equals("+")) {
					result = num1+num2;
				}else if(item.equals("-")) {
					result = num1-num2;
				}else if(item.equals("*")) {
					result = num1*num2;
				}else if(item.equals("/")) {
					result = num1/num2;
				}else {
					throw new RuntimeException("运算符有误");
				}
				stack.push(""+result);
			}
		}
		return Integer.parseInt(stack.pop());
		
	}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
中缀表达式后缀表达式是一种用于计算数学表达式的方法。在后缀表达式中,操作符位于操作数的后面。为了实现这个计算器,我们可以使用数据结构作为辅助工具。 首先,我们需要定义一个函数,这个函数会接收中缀表达式作为参数,并返回对应的后缀表达式。在这个函数中,我们可以遍历中缀表达式的每个元素。对于数字,我们可以直接将其添加到后缀表达式中。对于操作符,我们需要根据其优先级来判断是否需要将其弹出并添加到后缀表达式中。 具体步骤如下: 1. 创建一个空和一个空结果列。 2. 遍历中缀表达式的每个元素。 3. 如果遇到数字,将其添加到结果列中。 4. 如果遇到左括号,将其压入中。 5. 如果遇到右括号,将中的操作符弹出并添加到结果列中,直到遇到左括号为止。 6. 如果遇到操作符,比较其与操作符的优先级:如果操作符的优先级高于等于当前操作符,则将其弹出并添加到结果列中,重复此步骤直到操作符优先级小于当前操作符或为空。然后将当前操作符压入中。 7. 遍历完中缀表达式后,将中的所有操作符弹出并添加到结果列中。 最后,返回结果列即可得到后缀表达式。通过对后缀表达式的计算,我们可以得到最终的结果。 这个计算器可以使用C语言来实现。通过使用来保存操作符,并按照上述步骤进行遍历和计算,我们可以实现一个简单但有效的中缀表达式后缀表达式计算器
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值