Algo-Lab 2 Stack Queue ADT

news2024/12/31 7:31:10

Lab 2: Stack & Queue ADT

image-20240923223516163

Part 1

​ 这里只说一下最小栈的思路,我们可以在定义一个栈,来同步存储当前情况下的占的最小值。最小栈第一时间的想法可能是设定一个变量,每次push进来栈中的元素进行对比,保持最小值,但是这样做并没有考虑到如果POP时的各种情况。因此,我们设置一个最小值的栈,他和存储的栈同步Push和Pop,只是,它每次push 的是栈目前存储的元素中的最小的值,这样就解决了 Pop 后的最小值问题了。

public class StackMin<AnyType extends Comparable<AnyType>> implements StackInterface<AnyType> {
    private static final int MAX_SIZE = 1024;
    private AnyType[] xstack;
    private AnyType[] minstack;
    private int size;

    public StackMin() {
        this.xstack = (AnyType[]) new Object[MAX_SIZE];
        this.minstack = (AnyType[]) new Object[MAX_SIZE];
        this.size = 0;
    }

    @Override
    public int size() {
        return this.size;
    }

    @Override
    public AnyType pop() throws EmptyStackException {
        if (isEmpty()) {
            throw new EmptyStackException();
        }
        return this.xstack[--this.size];
    }

    @Override
    public AnyType peek() throws EmptyStackException {
        if (isEmpty()) {
            throw new EmptyStackException();
        }
        return this.xstack[this.size - 1];
    }

    @Override
    public void push(AnyType item) {
        if (this.size < MAX_SIZE) {
            this.xstack[this.size++] = item;
            if (size == 0 || item.compareTo(this.minstack[size - 1]) < 0) {
                this.minstack[this.size] = item;
            } else {
                this.minstack[this.size] = this.minstack[size - 1];
            }
        }
    }


    @Override
    public void clear() {
        this.size = 0;
    }

    @Override
    public boolean isEmpty() {
        return size() == 0;
    }

    public AnyType findMin() {
        return this.minstack[this.size - 1];
    }
}

image-20240923223533506

Part 2

​ 这个题目的主要思想是,寻找第一个比自己小的数距离,从暴力的角度来想,我每次遍历一个数字,就从这个数向前遍历,直到遇到比自己大的数为止,这样的时间复杂度是n方;考虑优化的话,可以进一步想到,如果前面的数比自己小,那么它的结果的距离范围的数字都会比自己小,则可以剪枝一部分遍历的时间;我们可以进一步的优化,设置一个栈,如果当前元素小于栈顶元素,则索引的距离即为所求;如果当前元素比栈顶元素值大的时候,则一直Pop出站,直到栈顶元素更大的时候,这时,两者的索引距离就是范围。下面是两种情况下的代码,一种是直接给了完整的数组可以查询的,一种是等待输入流随时输入随时输出的。

/**
     * Simple computeSpan static function
     * working on arrays
     */
    public static int[] computeSpan(int[] input) {
        int len = input.length;
        int[] spans = new int[len];
        Stack<Integer> stack = new Stack<>();

        for (int i = 0; i < len; i++) {
            while (!stack.isEmpty() && input[stack.peek()] <= input[i]) {
                stack.pop();
            }
            spans[i] = (stack.isEmpty()) ? (i + 1) : (i - stack.peek());
            stack.push(i);
        }

        return spans;
    }


/**
     * Compute the span of the input values
     * using a stack.
     * Complexity: THETA(n) where is n is the
     * number of values to compute the span of
     */
    public void computeSpan() {
        Stack<Integer> priceStack = new Stack<>();
        Stack<Integer> indexStack = new Stack<>();
        int day = 0;

        while (input.hasNextInt()) {
            int price = input.nextInt();
            int span = 1;

            while (!priceStack.isEmpty() && priceStack.peek() <= price) {
                priceStack.pop();
                indexStack.pop();
            }
            if (indexStack.isEmpty()) {
                span = day + 1;
            } else {
                span = day - indexStack.peek();
            }

            priceStack.push(price);
            indexStack.push(day);

            output.printf("value: %d span: %d\n", price, span);
            day++;
        }
    }

image-20240923223542933

Part 3

​ 用链表写一个队列就不说了,寻找pair,浅谈一下,暴力的话,n方的复杂度依次遍历;优化的话,放在哈希表中,减去O(n)的查询的复杂度

public static void showPairs(int n, String fileName) throws FileNotFoundException, EmptyQueueException {
        ListQueue<Integer> queue = new ListQueue<>();
        Scanner scanner = new Scanner(new File(fileName));

        while (scanner.hasNextInt()) {
            queue.offer(scanner.nextInt());
        }
        scanner.close();

        Map<Integer, Integer> map = new HashMap<>();
        int index = 0;
        while (!queue.isEmpty()) {
            Integer num = queue.poll();
            if (map.containsKey(num - n)) {
                System.out.println("(" + (num - n) + "," + num + ")");
            }
            map.put(num, index++);
        }
    }

image-20240923223552679

Part 4

​ 用栈来写一个队列,思路也很简单,使用两个栈,一个输入,一个输出,当输出栈为空时,将输入栈的值全部压到输出栈中

package tiei.aads.adt;

import java.util.Stack;

/**
 * A class for queues implemented with stacks
 */
public class StackQueue<AnyType> implements QueueInterface<AnyType> {
    private Stack<AnyType> instack = new Stack<>();
    private Stack<AnyType> outstack = new Stack<>();


    @Override
    public int size() {
        return this.instack.size() + this.outstack.size();
    }

    @Override
    public boolean isEmpty() {
        return this.instack.isEmpty() && this.outstack.isEmpty();
//        return QueueInterface.super.isEmpty();
    }

    @Override
    public void offer(AnyType item) {
        this.instack.push(item);
    }

    @Override
    public AnyType poll() throws EmptyQueueException {
        if(this.outstack.isEmpty()){
            while (this.instack.isEmpty()){
                this.outstack.push(this.instack.pop());
            }
        }
        return outstack.pop();
    }

    @Override
    public AnyType peek() throws EmptyQueueException {
        if(this.outstack.isEmpty()){
            while (this.instack.isEmpty()){
                this.outstack.push(this.instack.pop());
            }
        }
        return outstack.peek();
    }
}

image-20240923223607171

Part 5

​ 是一个经典的T形火车问题,主要思路就是,使用一个Map,存储下一个目标火车所在的栈,然后依次将不是目标的元素存储到另一个栈中(因为你需要考虑最简洁的移动方式,所以需要精准找到目标火车的位置;如果不需要最简洁的要求,完全可以在两个栈中依次寻找就跟我下面还没有优化完全的代码一样)(过段时间我一定改)

package tiei.aads.adt;

import java.util.*;

/**
 * A class to arrange train configuration
 */
public class TrainManagement {

    private String[] from; // the initial ordering
    private String[] to;   // the final ordering

    private StackInterface<String> U; // to hold the cars on track U(nsorted)
    private StackInterface<String> T; // to hold the cars on track T(emporary)
    private StackInterface<String> S; // to hold the cars on track S(orted)

    private Map<String, StackInterface<String>> map = new HashMap<>();
    
    /**
     * Build a TrainManagement object
     * Preconditions:
     * 'from' and 'to' have the same size N and are
     * both permutations of each other
     */
    public TrainManagement(String[] from, String[] to) {
        this.from = from;
        this.to = to;
        U = new ArrayStack<>();
        T = new ArrayStack<>();
        S = new ArrayStack<>();
        
        for (int i = from.length - 1; i >= 0; i--) {
            U.push(from[i]);
            map.put(from[i], U);
        }

    }

    /**
     * Output the basic move commands to transfer
     * the cars from the 'from' order on track U
     * to the 'to' order on track S
     */
    public void arrange() throws EmptyStackException {
        int toIndex = 0;
        while (toIndex < to.length) {
            String targetCar = to[toIndex];
            boolean found = false;
            while (!U.isEmpty()) {
                String car = U.pop();
                System.out.println("move car " + car + " from U to T");
                T.push(car);
                if (car.equals(targetCar)) {
                    found = true;
                    System.out.println("move car " + car + " from T to S");
                    T.pop();
                    toIndex++;
                    break;
                }
            }
            while (!T.isEmpty() && !found) {
                String car = T.pop();
                System.out.println("move car " + car + " from T to U");
                U.push(car);
            }
        }
    }


    /**
     * A short main for quick testing
     */
    public static void main(String[] args) throws EmptyStackException {
        String[] from = {"33", "11", "44", "22"};
        String[] to = {"11", "22", "33", "44"};
        TrainManagement tm = new TrainManagement(from, to);
        tm.arrange();
    }
    // expected output
    //
    // move car 33 from U to T
    // move car 11 from U to T
    // move car 11 from T to S
    // move car 44 from U to T
    // move car 22 from U to T
    // move car 22 from T to S
    // move car 44 from T to U
    // move car 33 from T to S
    // move car 44 from U to T
    // move car 44 from T to S
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2158892.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Redis渐进式遍历

我们知道&#xff0c;keys* 是一次性把所有的key都获取到&#xff0c;这个操作太危险&#xff0c;可能会一次性得到太多的key而阻塞服务器。但是通过渐进式遍历&#xff0c;既能够获取到所有的key&#xff0c;又能不会卡死服务器。 redis使用scan命令进行渐进式遍历&#xff0…

宠物去浮毛救星?希喂、小米、霍尼韦尔宠物空气净化器哪款好用

怎么有人放假也不开心&#xff1f; 快到的国庆假期真是愁死我了...本来我妈国庆去旅游&#xff0c;我就打算不回家&#xff0c;和我家猫过二人世界。结果突然有事&#xff0c;我妈取消出行&#xff0c;改成让我假期回家陪她。我回家容易&#xff0c;我家猫回去可难啊&#xff…

前端-js例子:todolist

实现效果图&#xff1a; 实现步骤&#xff1a; 1.body部分 1.首先&#xff0c;设置输入数据的框和按钮进行操作 2.设置一个表格标签&#xff08;有边框&#xff09;&#xff0c;首先在表头放置两列&#xff08;“事项”‘’操作&#xff09; <body><div class"…

初学者怎么入门大语言模型(LLM)?看完这篇你就懂了!

当前2024年&#xff0c;LLM领域发展日新月异&#xff0c;很多新的实用技术层出不穷&#xff0c;个人认为要跟上LLM的发展&#xff0c;需要掌握以下内容&#xff0c;并需要不断地跟踪学习。 入门LLM前置基础 深度学习基础知识&#xff1a;推荐李宏毅的深度学习课程Python和num…

数据结构2——单链表

目录 1.链表 1.1链表的概念及结构 1.2 链表的分类 ​编辑2.无头单链表的实现 1. 节点 2.遍历链表 3.动态增加新节点 4.查找&#xff08;修改&#xff09; 5.插入 5.1 尾插 5.2 头插 5.3 在pos之前插入x 5.4 在pos之后插入x 6.删除 6.1 尾删 6.2 头删 6.3 删除…

DPDK 简易应用开发之路 4:基于Pipeline模型的DNS服务器

本机环境为 Ubuntu20.04 &#xff0c;dpdk-stable-20.11.10 使用scapy和wireshark发包抓包分析结果 完整代码见&#xff1a;github Pipeline模型 DPDK Pipeline模型是基于Data Plane Development Kit&#xff08;DPDK&#xff09;的高性能数据包处理框架。它通过将数据流分为多…

基于SpringBoot+Vue+MySQL的旅游推荐管理系统

系统展示 用户前台界面 管理员后台界面 系统背景 随着社会的快速发展和人民生活水平的显著提高&#xff0c;旅游已成为人们休闲娱乐的重要方式。然而&#xff0c;面对海量的旅游信息和多样化的旅游需求&#xff0c;如何高效地管理和推荐旅游资源成为了一个亟待解决的问题。因此…

学习记录:js算法(四十三):翻转二叉树

文章目录 翻转二叉树我的思路网上思路递归栈 总结 翻转二叉树 给你一棵二叉树的根节点 root &#xff0c;翻转这棵二叉树&#xff0c;并返回其根节点 图一&#xff1a; 图二&#xff1a; 示例 1&#xff1a;&#xff08;如图一&#xff09; 输入&#xff1a;root [4,2,7,1…

大模型价格战,打到了负毛利,卷or不卷?

国产大模型淘汰赛在加速。这轮淘汰赛会持续一两年&#xff0c;只有少数真正具备实力的基础模型企业能继续活下去 中国市场的大模型价格战已经打了近半年。这轮价格战已经打到了负毛利&#xff0c;而且暂时没有停止迹象。头部云厂商仍在酝酿新一轮降价。这轮降价会在今年9月下旬…

视频单目标跟踪研究

由于对视频单目标跟踪并不是很熟悉&#xff0c;所以首先得对该领域有个大致的了解。 视频目标跟踪是计算机视觉领域重要的基础性研究问题之一&#xff0c;是指在视频序列第一帧指定目标 后&#xff0c;在后续帧持续跟踪目标&#xff0c;即利用边界框&#xff08;通常用矩形框表…

printf 命令:格式化输出

一、命令简介 ​printf​ 命令在 Linux 系统中用于格式化并打印字符串到标准输出。它是 C 语言中 printf ​函数的命令行版本&#xff0c;因此其格式化选项与 C 语言中的非常相似。 相关命令&#xff1a; echo&#xff1a;通常使用 echo&#xff0c;它比较简单。printf&…

你们用过微信CRM管理系统吗?

微信CRM管理系统是近年来流行的管理软件&#xff0c;在市场上得到了很高的认可。许多企业正在应用微信CRM管理系统&#xff0c;那系统具体有些什么功能呢&#xff1f; 1、聚合聊天&#xff0c;可以管理多个微信号 2、批量多号自动加好友任务&#xff0c;设置好时间间隔以及加人…

《论软件系统架构风格》写作框架,软考高级系统架构设计师

论文真题 系统架构风格&#xff08;System Architecture Style&#xff09;是描述某一特定应用领域中系统组织方式的惯用模式。架构风格定义了一个词汇表和一组约束&#xff0c;词汇表中包含一些构件和连接件类型&#xff0c;而这组约束指出系统是如何将这些构件和连接件组合起…

李沐对大模型趋势的几点判断,小模型爆发了!

李沐是上海交通大学 2011 届计算机科学与工程系本硕系友。他曾担任亚马逊资深首席科学家&#xff0c;加州大学伯克利分校和斯坦福大学的访问助理教授&#xff0c;是前 Marianas Labs 联合创始人&#xff0c;深度学习框架 Apache MXNet 的创始人之一。目前是 BosonAI 联合创始人…

C++之STL—string容器

本质&#xff1a;类 class 封装了很多方法&#xff1a;查找find&#xff0c;拷贝copy&#xff0c;删除delete 替换replace&#xff0c;插入insert 构造函数 赋值操作 assign&#xff1a; 字符串拼接 &#xff0b; append&#xff1a; string查找和替换 没查找到&#xff0c;po…

【刷题2—滑动窗口】最大连续1的个数lll、将x减到0的最小操作数

目录 一、最大连续1的个数lll二、将x减到0的最小操作数 一、最大连续1的个数lll 题目&#xff1a; 思路&#xff1a; 问题转换为&#xff1a;找到一个最长子数组&#xff0c;这个数组里面0的个数不能超过k个 定义一个变量count&#xff0c;来记录0的个数&#xff0c;进窗口、…

时序预测 | Python实现KAN+LSTM时间序列预测

时序预测 | Python实现KAN+LSTM时间序列预测 目录 时序预测 | Python实现KAN+LSTM时间序列预测预测效果基本介绍程序设计预测效果 基本介绍 时序预测 | KAN+LSTM时间序列预测(Python) KAN作为这两年最新提出的机制,目前很少人用,很适合作为时间序列预测的创新点,可以结合…

【重学 MySQL】三十八、group by的使用

【重学 MySQL】三十八、group by的使用 基本语法示例示例 1: 计算每个部门的员工数示例 2: 计算每个部门的平均工资示例 3: 结合 WHERE 子句 WITH ROLLUP基本用法示例注意事项 注意事项 GROUP BY 是 SQL 中一个非常重要的子句&#xff0c;它通常与聚合函数&#xff08;如 COUNT…

MySQL和SQL的区别简单了解和分析使用以及个人总结

MySQL的基本了解 运行环境&#xff0c;这是一种后台运行的服务&#xff0c;想要使用必须打开后台服务&#xff0c;这个后台服务启动的名字是在安装中定义的如下图&#xff08;个人定义MySQL88&#xff09;区分大小写图片来源 可以使用命令net start/stop 服务名&#xff0c;开…

实验十八:IIC-EEPROM实验

这个实验比较复杂,是目前第一个多文件项目 KEY1-4:P3^0-P3^3 IIC_SCL=P2^1; IIC_SDA=P2^0; //定义数码管位选信号控制脚 LSA=P2^2; LSB=P2^3; LSC=P2^4; 代码 main.c #include "public.h" #in