Java数据结构之栈

本文介绍了Java数据结构中的栈,并通过数组实现了栈的基本操作,包括入栈、出栈和显示栈内元素。此外,还展示了如何使用两个栈实现一个简单的四则运算计算器,该计算器能处理中缀表达式,支持两位数的运算。在计算过程中,通过比较运算符的优先级来决定何时进行运算。
摘要由CSDN通过智能技术生成

栈是什么

  • 栈又名堆栈,是一种运算受限的线性表。仅限在表尾进行插入和删除操作的线性表,这一端被称为栈顶,而另一端称为栈底。向一个栈插入新元素又称作进栈、入栈或压栈,它是把新元素放到栈顶元素的上面,使之成为新的栈顶元素;从一个栈删除元素又称作出栈或退栈,它是把栈顶元素删除掉,使其相邻的元素成为新的栈顶元素。百度百科
    百度找的

数组模拟栈

思想

  • 定义一个top表示栈顶,初始化其值为-1
  • 入栈,当有数据入栈时,top上移指向没有数据的位置
top++;
stack[top]=value;
  • 出栈,输出栈顶元素,然后top指向下一个元素,下一个元素成为新的栈顶元素
int value=stack[top];
top--;

代码实现

public class ArrayStack {
	
	private int maxSize;
	
	private int[] stack;
	
	private int top;
	
	public ArrayStack(int maxSize) {
		this.maxSize=maxSize;
		stack=new int[this.maxSize];
		this.top=-1;
	}
	
	public boolean isFull() {//判断栈是否满
		return top==maxSize-1;
	}
	
	public boolean isEmpty() {//判断栈是否空
		return top==-1;
	}
	
	public void push(int value) {
		if(isFull()) {
			System.out.printf("栈满,数据:%d\n",value);
			return;
		}
		top++;
		stack[top]=value;
	}
	
	public int pop() {
		if(isEmpty()) {
			throw new RuntimeException("栈为空,请先插入数据");
		}
		int value=stack[top];
		top--;
		return value;
	}
	
	public void show() {
		if(isEmpty()) {
			System.out.println("栈为空,请先插入数据");
			return;
		}
		for(int i=top;i>=0;i--) {
			System.out.printf("stack[%d]=%d\n",i,stack[i]);
		}
	}
	
	public static void main(String[] args) {
		ArrayStack as=new ArrayStack(4);
		char key=' ';
		Scanner scanner=new Scanner(System.in);
		boolean loop=true;
		
		while(loop) {
			System.out.println("s(show)展示栈");
			System.out.println("i(push)进栈");
			System.out.println("o(pop)出栈一个数据");
			System.out.println("e(exit)退出");
			key=scanner.next().charAt(0);
			switch(key) {
			case 's':
				as.show();
				break;
			case 'i':
				System.out.println("请输入要插入的数据");
				int value=scanner.nextInt();
				as.push(value);
				break;
			case 'o':
				as.pop();
				break;
			case 'e':
				scanner.close();
				loop=false;
				break;
			default:
				break;
			}
		}
		System.out.println("退出");

	}

}

运行结果

s(show)展示栈
i(push)进栈
o(pop)出栈一个数据
e(exit)退出
i
请输入要插入的数据
1
s(show)展示栈
i(push)进栈
o(pop)出栈一个数据
e(exit)退出
i
请输入要插入的数据
2
s(show)展示栈
i(push)进栈
o(pop)出栈一个数据
e(exit)退出
s
stack[1]=2
stack[0]=1
s(show)展示栈
i(push)进栈
o(pop)出栈一个数据
e(exit)退出
o
s(show)展示栈
i(push)进栈
o(pop)出栈一个数据
e(exit)退出
s
stack[0]=1
s(show)展示栈
i(push)进栈
o(pop)出栈一个数据
e(exit)退出
o
s(show)展示栈
i(push)进栈
o(pop)出栈一个数据
e(exit)退出
s
栈为空,请先插入数据
s(show)展示栈
i(push)进栈
o(pop)出栈一个数据
e(exit)退出
e
退出

数组栈实现简单的四则运算的计算器(支持两位数)

  • 实现该计算器需要两个栈,数栈用于存放数字,符号栈存放运算符。用的是中缀表达式。
  • 为了实现该计算器,要在前面的栈的代码的基础上增加得到当前栈顶元素、返回优先级、判断字符是否为运算符和计算的方法
  • 新增代码如下
public int showCyrrentTop() {//展示当前栈顶元素,不取出
		return stack[top];
	}
	
	public int priority(int oper) {//判断运算符的优先级
		if(oper=='*'||oper=='/') {
			return 1;
		}else if(oper=='*'||oper=='/') {
			return 0;
		}else return -1;
	}
	
	public boolean isOper(char value) {//判断字符是否为运算符
		return value=='+'||value=='-'||value=='*'||value=='/';
	}
	
	public int calculate(int num1,int num2,int oper) {//运算
		int result=0;
		switch (oper) {
		case '+':
			result=num2+num1;
			break;
		case '-':
			result=num2-num1;
			break;
		case '*':
			result=num2*num1;
			break;
		case '/':
			result=num2/num1;
			break;
		default:
			break;
		}
		return result;
		
	}

这里的priority方法放置的参数类型是int,但是可以传入char类型的变量,具体为什么详见具体原因

思想
  1. 设置一个变量index来遍历表达式
  2. 如果扫描到的是数字就入数栈
  3. 如果发现扫描到的是一个运算符,分2种情况的情况
  4. 情况1:当前符号栈为空,则该运算符直接入栈
  5. 情况2:当前符号栈不为空,就和当前栈顶元素的符号进行优先级比较,如果希望入栈的运算符优先级小于或等于栈顶元素的符号的优先级,则需要先从数栈中取出2个数字以及栈顶元素的符号进行运算,运算得到的数据再存储入数栈中,再将希望入栈的运算符入栈。反之,如果希望入栈的运算符的优先级大于栈顶元素的符号的优先级,就直接将希望入栈的运算符入栈。
  6. 表达式扫描完毕后,就将数栈和符号栈中的数据和运算符取出并求出结果。
  7. 最后只有数栈存在一个数据,这个数据就是表达式的结果。
代码实现
public class Calculator {
	
	
	
	public static void simpleCaculator(String expression) {
		ArrayStack numStack=new ArrayStack(10);//数栈
		ArrayStack operStack=new ArrayStack(10);//运算符栈
		int num1=0;
		int num2=0;
		int result=0;//num1、num2和result用于临时存放数据
		int oper=0;
		char index=' ';//用于遍历表达式
		String keepNum="";//用于拼接数字
		for(int i=0;i<expression.length();i++) {
			index=expression.substring(i, i+1).charAt(0);
			//一次取得表达式中的一个字符
			if (!operStack.isOper(index)) {// 如果不是运算符
				keepNum += index;
				if (i == (expression.length() - 1)) {// 判断是否是最后一位
					numStack.push(Integer.parseInt(keepNum));
				} else {
					// 查看当前位置的下一个位置的数据是不是数字,不是就将拼接的数字入栈
					if (operStack.isOper(expression.substring(i + 1, i + 2).charAt(0))) {
						numStack.push(Integer.parseInt(keepNum));// 让拼接的数字入栈
						keepNum = "";//拼接好的数字入完栈以后,keepNum重新置为"",以便下次别的数字使用
					}
				}

			}else {//如果是运算符
				if(operStack.isEmpty()) {//如果运算符栈为空
					operStack.push(index);
				}else {//不为空
					if(operStack.priority(index)<=operStack.priority(operStack.showCyrrentTop())) {
						//如果优先级小于等于当前符号栈栈顶的优先级,就取出当前栈顶元素
						//并取出数栈内的最靠近栈顶的2个数,进行运算
						num1=numStack.pop();
						num2=numStack.pop();
						oper=operStack.pop();
						result=numStack.calculate(num1, num2, oper);
						numStack.push(result);
						//运算完后,将结果插入数据栈
						operStack.push(index);
						//此时,再将希望入栈的运算符入栈
					}else {//如果优先级大于符号栈当前栈顶元素的优先级就直接插入
						operStack.push(index);
					}
				}
			}
		}
		while(true) {
			if(operStack.isEmpty()) {//当符号栈为空则说明运算完毕,跳出循环
				break;
			}
			num1=numStack.pop();
			num2=numStack.pop();
			oper=operStack.pop();
			result=numStack.calculate(num1, num2, oper);
			numStack.push(result);
		}
		System.out.println(numStack.pop());
	}

	public static void main(String[] args) {
		simpleCaculator("2+3*4-6");
		simpleCaculator("20+30*40-60");
	}

}

运行结果

8
1160
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值