Java面试知识点(六十七)数据结构之栈

154 篇文章 5 订阅
43 篇文章 2 订阅

定义

栈是只能在某一端插入和删除的特殊线性表。

在这里插入图片描述


java中的栈

java有现成的工具类Stack

import java.util.Stack;

工具类Stack提供了几个现成的操作栈的方法

  • push() 压栈,向栈顶存入一个元素
  • pop() 弹栈,从栈顶取出一个元素,并返回该元素
  • peek() 返回栈顶的元素,但是并不取出
  • empty() 判断栈是否为空

栈的实例

【例1】括号的匹配(表达式的合法性检查)

【问题描述】
假设一个表达式有英文字母(小写)、运算符(+,—,*,/)和左右小(圆)括号构成。请编写一个程序检查表达式中的左右圆括号是否匹配,若匹配,则返回“true”;否则返回“false”。假设表达式长度小于255,左圆括号少于20个。

【代码示例】

package base.datastructure.stack;

import java.util.Scanner;
import java.util.Stack;

public class Brackets {
    /**
     * 括号匹配,使用辅助结构——栈
     * 从左向右扫描,遇到左括号压栈,遇到右括号弹栈
     * 成功——扫描完毕,堆栈为空
     * 失败——
     * 1.左括号多余右括号,扫描完毕,不为空;
     * 2.右括号多余左括号,弹栈失败;
     * 3.左右括号一样多,但是右括号在左括号前面,弹栈失败;
     * */
    public boolean method(String str) {
        char[] chars = str.toCharArray();
        Stack<Character> stack = new Stack<>();
        for (Character a : chars) {
            if (a.equals('(')) {
                stack.push('(');
            }
            if (a.equals(')')) {
                if (stack.empty()) {
                    return false;
                } else {
                    stack.pop();
                }
            }
        }
        if (stack.empty()) {
            return true;
        } else {
            return false;
        }
    }

    public static void main(String[] args) {
        // String str = "";
        Scanner scan = new Scanner(System.in);
        String str = scan.next();
        Brackets brackets = new Brackets();
        System.out.println(brackets.method(str));
    }
}


【例2】编程求一个后缀表达式的值

【问题描述】
从键盘读入一个后缀表达式(字符串),只含有0-9组成的运算数及加(+)、减(—)、乘(.)、除(/)四种运算符。每个运算数之间用一个空格隔开,不需要判断给你的表达式是否合法。

【算法分析】
后缀表达式的处理过程很简单,过程如下:扫描后缀表达式,凡遇操作数则将之压进堆栈,遇运算符则从堆栈中弹出两个操作数进行该运算,将运算结果压栈,然后继续扫描,直到后缀表达式被扫描完毕为止,此时栈底元素即为该后缀表达式的值。
比如,16–9*(4+3)转换成后缀表达式为:
16□9□4□3□+*–,

【代码示例】

package base.datastructure.stack;

import java.util.Scanner;
import java.util.Stack;

public class Suffix {
    /**
     * 后缀表达式,
     * 遇到数字压栈,遇到符号把栈顶的两个元素拿出来,进行计算
     * 计算之后,把结果再次压栈,最后的结果就是最终结果
     *
     * 如何把字符串转换为int类型:
     * 1. 使用String的valueOf()
     * int num = Integer.parseInt(String.valueOf(a));
     * 2. 使用ascii码(仅限于char类型)
     * int num = (int)a - (int)'0';
     * */
    public int method(String str) {
        String[] ss = str.split(" ");
        Stack<String> stack = new Stack<>();
        for (String s : ss) {
            switch (s) {
                case "+" :
                    String s11 = stack.pop();
                    String s12 = stack.pop();
                    int i11 = Integer.parseInt(String.valueOf(s11));
                    int i12 = Integer.parseInt(String.valueOf(s12));
                    int i1 = i11 + i12;
                    stack.push(i1+"");
                    break;
                case "-" :
                    String s21 = stack.pop();
                    String s22 = stack.pop();
                    int i21 = Integer.parseInt(String.valueOf(s21));
                    int i22 = Integer.parseInt(String.valueOf(s22));
                    int i2 = i22 - i21;
                    stack.push(i2+"");
                    break;
                case "*" :
                    String s31 = stack.pop();
                    String s32 = stack.pop();
                    int i31 = Integer.parseInt(String.valueOf(s31));
                    int i32 = Integer.parseInt(String.valueOf(s32));
                    int i3 = i31 * i32;
                    stack.push(i3+"");
                    break;
                case "/" :
                    String s41 = stack.pop();
                    String s42 = stack.pop();
                    int i41 = Integer.parseInt(String.valueOf(s41));
                    int i42 = Integer.parseInt(String.valueOf(s42));
                    int i4 = i42 / i41;
                    stack.push(i4+"");
                    break;
                default :
                    stack.push(s);
            }
        }
        if (stack.empty()) {
            return 0;
        }
        return Integer.parseInt(String.valueOf(stack.pop()));
    }

    public static void main(String[] args) {
        String str = "16 9 4 3 + * -";
        Suffix suffix = new Suffix();
        System.out.println(suffix.method(str));
    }
}


【问题描述】
有一个火车站,铁路如图所示,每辆火车从A驶入,再从B方向驶出,同时它的车厢可以重新组合。假设从A方向驶来的火车有n节(n<=1000),分别按照顺序编号为1,2,3,…,n。假定在进入车站前,每节车厢之间都不是连着的,并且它们可以自行移动到B处的铁轨上。另外假定车站C可以停放任意多节车厢。但是一旦进入车站C,它就不能再回到A方向的铁轨上了,并且一旦当它进入B方向的铁轨,它就不能再回到车站C。
在这里插入图片描述
负责车厢调度的工作人员需要知道能否使它以a1,a2,…,an的顺序从B方向驶出,请来判断能否得到指定的车厢顺序。

【输入】
输入文件的第一行为一个整数n,其中n<=1000,表示有n节车厢,第二行为n个数字,表示指定的车厢顺序。

【输出】
如果可以得到指定的车厢顺序,则输出一个字符串
”YES”,否则输出”NO”(注意要大写,不包含引号)。

【输入样例】
5
5 4 3 2 1

【输出样例】
YES

【代码示例】

package base.datastructure.stack;

import java.util.Stack;

public class Car {
    /**
     * 车厢调度
     * 驶入序号A,数组,需要一个游标记录进入C的最大车号
     * 驶出序号B,目标数组,需要判断是否正确
     * 中转序号C,存储栈,
     *
     * 思路:遍历给定目标数组,设定一个游标,初始值为0,
     * 如果游标小于数组值,则
     * 把游标到给定数组之间的数字全部存入栈中,同时弹栈一次
     * 如果游标大于数组值,则
     * 弹栈一次,并比较当前数组跟弹出的值,不同则错误,相同继续
     * 遍历完成之后,栈为空,正确
     * */
    public String method(int[] cars) {
        int n = cars.length;
        Stack<Integer> stack = new Stack<>();
        // 定位的游标
        int flag = 0;
        for (int i=0; i<n; i++) {
            if (cars[i] > flag) {
                // 当游标跟车号一致跳出,此时一致的车号也加入栈中
                while (flag < cars[i]) {
                    flag ++;
                    stack.push(flag);
                }
                // 弹栈一次,为了进行比对车号
                stack.pop();
            } else {
                int car = stack.pop();
                if (car != cars[i]) {
                    return "NO";
                }
            }
        }
        if (stack.empty()) {
            return "YES";
        }
        return "NO";
    }

    public static void main(String[] args) {
        int[] a = {1,2,5,3,4};
        System.out.println(new Car().method(a));
    }
}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值