数据结构与算法——Java实现 19.队列

news2024/9/28 5:40:50

目录

一、概述

二、链表实现队列

接口定义

 接口实现类

测试类 

三、环形数组实现队列

优点

下标计算

判满和判空

判满

判空

辅助变量size判空和判满

方法1

 接口定义

接口实现类

测试类 

方式2

接口定义

接口实现类

测试类

方法3

 接口定义

接口实现类

测试类 


生活鲜少给人留下退路

                        —— 24.9.27

一、概述

计算机科学中,queue 是以顺序的方式维护的一组数据集合,在一端添加数据,从另一端移除数据。习惯来说,添加的一端称为尾,移除的一端称为头,就如同生活中的排队买商品

二、链表实现队列

下面以单向环形带哨兵链表方式来实现队列

接口定义

offer:向队列尾部插入值

poll:从队列头部获取值,并移除

peek:从队列头获取值,不移除

isEmpty:检查队列是否为空

isFull:检查队列是否为满

public interface Queue<E> {
    /*
        向队列尾部插入值
        Params:value-待插入值
        Returns:插入成功返回true,插入失败返回false
     */
    boolean offer(E e);

    /*
        从队列头获取值,并移除
        Returns:如果队列非空返回头部值,否则返回null
     */
    E poll();

    /*
        从队列头获取值,不移除
        Returns:如果队列非空返回队头值,否则返回null
     */
    E peek();

    /*
        检查队列是否为空
        Return:空返回true,否则返回false
     */
    boolean isEmpty();

    /*
        检查队列是否为满
        Return:满返回true,否则返回false
     */
    boolean isFull();
}

 接口实现类

import java.util.Iterator;

// 用泛型好处:1.用null代表特殊值   2.代表更多类型
public class LinkedListQueue<E>
        implements Queue<E>,Iterable<E> {

    // 静态内部结点类
    private static class Node<E>{
        E value;
        Node<E> next;

        public Node(E value, Node<E> next){
            this.value = value;
            this.next = next;
        }
    }

    // 定义队列的头结点和尾节点
    Node<E> head = new Node<>(null,null);
    Node<E> tail = head;
    private int size = 0; // 当前节点数
    private int capacity = 10; // 队列最大容量

    public LinkedListQueue(int capacity) {
        this.capacity = capacity;
        tail.next = head;
    }

    public LinkedListQueue() {
        tail.next = head;
    }

    /*
        队列插入方法,在尾部插入
        Params:value-待插入值
        Returns:插入成功返回true,插入失败返回false
     */
    @Override
    public boolean offer(E e) {
        if(isFull()){
            return false;
        }
        Node<E> newNode = new Node<>(e,head);
        tail.next = newNode;
        tail = newNode;
        size++;
        return true;
    }

    /*
        从队头获取值,并移除
        Returns:如果队列非空返回队头值,否则返回null
     */
    @Override
    public E poll() {
        if (isEmpty()){
            return null;
        }
        Node<E> first = head.next;
        head.next = first.next;
        if (first == tail){
            tail = head;
        }
        size--;
        return first.value;
    }

    /*
        从队列头获取值,不移除
        Returns:如果队列非空返回队头值,否则返回null
    */
    @Override
    public E peek() {
        if(isEmpty()){
            return null;
        }
        return head.next.value;
    }

    /*
        检查队列是否为空
        Return:空返回true,否则返回false
    */
    @Override
    public boolean isEmpty() {
        return head == tail;
    }

    /*
        检查队列是否为满
        Return:满返回true,否则返回false
    */
    @Override
    public boolean isFull() {
        return size == capacity;
    }

    // 队列遍历方法 迭代器
    @Override
    public Iterator<E> iterator() {
        return new Iterator<E>() {
            Node<E> current = head.next;
            @Override
            public boolean hasNext() {
                return current != head;
            }

            @Override
            public E next() {
                E value = current.value;
                current = current.next;
                return value;
            }
        };
    }
}

测试类 

import org.junit.Test;

import java.util.List;

import static org.junit.jupiter.api.Assertions.*;

public class TestLinkedListQueue {
    // 向队列尾部插入值
    @Test
    public void offer() {
        LinkedListQueue<Integer> queue = new LinkedListQueue<>();
        queue.offer(1);
        queue.offer(2);
        queue.offer(3);
        queue.offer(4);
        queue.offer(5);
        assertIterableEquals(queue,List.of(1,2,3,4,5));
    }

    // 从队列头获取值,不移除
    @Test
    public void peek(){
        LinkedListQueue<Integer> queue = new LinkedListQueue<>();
        assertNull(queue.peek());
        queue.offer(1);
        assertEquals(1,queue.peek());
        queue.offer(2);
        assertEquals(1,queue.peek());
        queue.offer(3);
        assertEquals(1,queue.peek());
    }

    // 从队头获取值,并移除
    @Test
    public void poll() {
        LinkedListQueue<Integer> queue = new LinkedListQueue<>();
        queue.offer(1);
        queue.offer(2);
        queue.offer(3);
        queue.offer(4);
        queue.offer(5);

        assertEquals(1,queue.poll());
        assertEquals(2,queue.poll());
        assertEquals(3,queue.poll());
        assertEquals(4,queue.poll());
        assertEquals(5,queue.poll());
        assertNull(queue.poll());
    }

    // 向有限队列头部加入元素
    @Test
    public void offerLimit(){
        LinkedListQueue<Integer> queue = new LinkedListQueue<>(3);
        queue.offer(1);
        queue.offer(2);
        queue.offer(3);
        queue.offer(4);
        queue.offer(5);
        assertIterableEquals(queue,List.of(1,2,3));
    }

}

三、环形数组实现队列

环形数组:

        大小固定,首尾相连的数组

        环形数组是一种逻辑上形成环形结构的数组,它在物理上通常是一个普通的线性数组,但在访问和操作时采用特定的逻辑来处理边界条件,使得元素可以从数组的末尾“循环”到开头,或者从开头“循环”到末尾。这种结构常用于实现循环队列、滑动窗口和约瑟夫环等问题,因为它避免了传统数组的越界问题,并且具有空间效率高、适合FIFO(先进先出)操作等优点。

环形数组的特点

① 逻辑环形:环形数组在逻辑上形成一个闭环,数组的最后一个元素与第一个元素相连。

② 无边界问题:由于索引是循环的,因此不存在传统数组的越界问题。

③ 空间效率高:环形数组可以充分利用数组空间,避免不必要的空间浪费。

④ 适合特定操作:如循环队列、滑动窗口等,这些操作在环形数组上实现起来更加高效。

环形数组的应用

① 循环队列:队列是一种先进先出(FIFO)的数据结构,而循环队列则是使用环形数组来实现的一种队列。在循环队列中,当队列的尾部达到数组的末尾时,下一个元素将插入到数组的开头,从而形成一个循环。

② 滑动窗口:滑动窗口是一种常用于数组/字符串处理的算法技巧,它可以在线性时间内解决一些看似需要嵌套循环的问题。环形数组可以用于实现滑动窗口的某些变体,特别是当窗口大小固定且需要循环移动时。

③ 约瑟夫环问题:约瑟夫环问题是一个著名的数学问题,描述的是n个人围成一圈,从第一个人开始报数,报到m的人出圈,然后从下一个人重新开始报数,如此循环直到所有人出圈。环形数组可以很好地模拟这个问题中的环形结构。

优点

        1.对比普通数组,起点和终点更为自由,不用考虑数据移动

        2.“环“意味着不会存在【越界】问题

        3.数组性能更佳

        4.环形数组比较适合实现有界队列、RingBuffer 等

下标计算

索引位置 =  (cur + step) % length

cur:当前指针位置

step:前进步数

length:数组长度

判满和判空

判满

(尾指针+1)% 数组长度 = 头指针

判空

头指针 = 尾指针

辅助变量size判空和判满

方法1

使用头尾指针判断队列空和满的情况

 接口定义

public interface Queue<E> {
    /*
        向队列尾部插入值
        Params:value-待插入值
        Returns:插入成功返回true,插入失败返回false
     */
    boolean offer(E e);

    /*
        从队列头获取值,并移除
        Returns:如果队列非空返回头部值,否则返回null
     */
    E poll();

    /*
        从队列头获取值,不移除
        Returns:如果队列非空返回队头值,否则返回null
     */
    E peek();

    /*
        检查队列是否为空
        Return:空返回true,否则返回false
     */
    boolean isEmpty();

    /*
        检查队列是否为满
        Return:满返回true,否则返回false
     */
    boolean isFull();
}

接口实现类

import java.util.Iterator;

public class ArrayQueue1<E> implements Queue<E>,Iterable<E> {
    private final E[] array;
    private int head = 0;
    private int tail = 0;

    public ArrayQueue1(int capacity) {
        array = (E[])new Object[capacity+1];
    }

    // 从队列尾部加入元素
    @Override
    public boolean offer(E e) {
        if (isFull()){
            return false;
        }
        array[tail] = e;
        tail = (tail + 1) % array.length;
        return true;
    }

    // 从队列头部移除元素
    @Override
    public E poll() {
        if (isEmpty()){
            return null;
        }
        E value = array[head];
        head = (head + 1) % array.length;
        return value;
    }

    // 获取队列头部元素值
    @Override
    public E peek() {
        if (isEmpty()){
            return null;
        }
        return array[head];
    }

    @Override
    public boolean isEmpty() {
        return head == tail;
    }

    @Override
    public boolean isFull() {
        return (tail+1) % array.length == head;
    }

    @Override
    public Iterator<E> iterator() {
        return new Iterator<E>() {
            int cursor = head;

            @Override
            public boolean hasNext() {
                return cursor != tail;
            }

            @Override
            public E next() {
                E value = array[cursor];
                cursor = (cursor + 1) % array.length;
                return value;
            }
        };
    }
}

测试类 

import org.junit.Test;

import java.util.List;

import static org.junit.jupiter.api.Assertions.*;
import static org.junit.jupiter.api.Assertions.assertIterableEquals;

public class TestArrayQueue1 {
    // 向队列尾部插入值
    @Test
    public void offer() {
        ArrayQueue1<Integer> queue = new ArrayQueue1<>(5);
        queue.offer(1);
        queue.offer(2);
        queue.offer(3);
        queue.offer(4);
        queue.offer(5);
        assertIterableEquals(queue, List.of(1,2,3,4,5));
    }

    // 从队列头获取值,不移除
    @Test
    public void peek(){
        ArrayQueue1<Integer> queue = new ArrayQueue1<>(5);
        assertNull(queue.peek());
        queue.offer(1);
        assertEquals(1,queue.peek());
        queue.offer(2);
        assertEquals(1,queue.peek());
        queue.offer(3);
        assertEquals(1,queue.peek());
    }

    // 从队头获取值,并移除
    @Test
    public void poll() {
        ArrayQueue1<Integer> queue = new ArrayQueue1<>(5);
        queue.offer(1);
        queue.offer(2);
        queue.offer(3);
        queue.offer(4);
        queue.offer(5);

        assertEquals(1,queue.poll());
        assertEquals(2,queue.poll());
        assertEquals(3,queue.poll());
        assertEquals(4,queue.poll());
        assertEquals(5,queue.poll());
        assertNull(queue.poll());
    }

    // 向有限队列头部加入元素
    @Test
    public void offerLimit(){
        ArrayQueue1<Integer> queue = new ArrayQueue1<>(3);
        queue.offer(1);
        queue.offer(2);
        queue.offer(3);
        queue.offer(4);
        queue.offer(5);
        assertIterableEquals(queue,List.of(1,2,3));
    }
}

方式2

引入一个辅助变量size,记录队列中的元素个数,直接通过用数组长度和size变量比较,判断队列空还是满。

接口定义

public interface Queue<E> {
    /*
        向队列尾部插入值
        Params:value-待插入值
        Returns:插入成功返回true,插入失败返回false
     */
    boolean offer(E e);

    /*
        从队列头获取值,并移除
        Returns:如果队列非空返回头部值,否则返回null
     */
    E poll();

    /*
        从队列头获取值,不移除
        Returns:如果队列非空返回队头值,否则返回null
     */
    E peek();

    /*
        检查队列是否为空
        Return:空返回true,否则返回false
     */
    boolean isEmpty();

    /*
        检查队列是否为满
        Return:满返回true,否则返回false
     */
    boolean isFull();
}

接口实现类

import java.util.Iterator;

public class ArrayQueue2<E> implements Queue<E>,Iterable<E> {
    private final E[] array;
    private int head = 0;
    private int tail = 0;
    private int size = 0;

    public ArrayQueue2(int capacity) {
        array = (E[]) new Object[capacity];
    }

    // 从队列尾部加入元素
    @Override
    public boolean offer(E e) {
        if (isFull()){
            return false;
        }
        array[tail] = e;
        tail = (tail + 1) % array.length;
        size++;
        return true;
    }

    // 从队列头部移除元素
    @Override
    public E poll() {
        if (isEmpty()){
            return null;
        }
        E value = array[head];
        head = (head + 1) % array.length;
        size--;
        return value;
    }

    // 获取队列头部元素值
    @Override
    public E peek() {
        if (isEmpty()){
            return null;
        }
        return array[head];
    }

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

    @Override
    public boolean isFull() {
        return size == array.length;
    }

    @Override
    public Iterator<E> iterator() {
        return new Iterator<E>() {
            int cursor = head;
            int count = 0;

            @Override
            public boolean hasNext() {
                return count < size;
            }

            @Override
            public E next() {
                E value = array[cursor];
                cursor = (cursor + 1) % array.length;
                count++;
                return value;
            }
        };
    }
}

测试类

import org.junit.Test;

import java.util.List;

import static org.junit.jupiter.api.Assertions.*;
import static org.junit.jupiter.api.Assertions.assertIterableEquals;

public class TestArrayQueue2 {
    // 向队列尾部插入值
    @Test
    public void offer() {
        ArrayQueue2<Integer> queue = new ArrayQueue2<>(5);
        queue.offer(1);
        queue.offer(2);
        queue.offer(3);
        queue.offer(4);
        queue.offer(5);
        assertIterableEquals(queue, List.of(1,2,3,4,5));
    }

    // 从队列头获取值,不移除
    @Test
    public void peek(){
        ArrayQueue2<Integer> queue = new ArrayQueue2<>(5);
        assertNull(queue.peek());
        queue.offer(1);
        assertEquals(1,queue.peek());
        queue.offer(2);
        assertEquals(1,queue.peek());
        queue.offer(3);
        assertEquals(1,queue.peek());
    }

    // 从队头获取值,并移除
    @Test
    public void poll() {
        ArrayQueue2<Integer> queue = new ArrayQueue2<>(5);
        queue.offer(1);
        queue.offer(2);
        queue.offer(3);
        queue.offer(4);
        queue.offer(5);

        assertEquals(1,queue.poll());
        assertEquals(2,queue.poll());
        assertEquals(3,queue.poll());
        assertEquals(4,queue.poll());
        assertEquals(5,queue.poll());
        assertNull(queue.poll());
    }

    // 向有限队列头部加入元素
    @Test
    public void offerLimit(){
        ArrayQueue2<Integer> queue = new ArrayQueue2<>(3);
        queue.offer(1);
        queue.offer(2);
        queue.offer(3);
        queue.offer(4);
        queue.offer(5);
        assertIterableEquals(queue,List.of(1,2,3));
    }
}

方法3

head和tail直接存储指针值,tail存储最后一个元素的指针值,计算tail存储指针值指向的索引,tail并不直接指向索引不把计算结果存入head和tail中

 接口定义

public interface Queue<E> {
    /*
        向队列尾部插入值
        Params:value-待插入值
        Returns:插入成功返回true,插入失败返回false
     */
    boolean offer(E e);

    /*
        从队列头获取值,并移除
        Returns:如果队列非空返回头部值,否则返回null
     */
    E poll();

    /*
        从队列头获取值,不移除
        Returns:如果队列非空返回队头值,否则返回null
     */
    E peek();

    /*
        检查队列是否为空
        Return:空返回true,否则返回false
     */
    boolean isEmpty();

    /*
        检查队列是否为满
        Return:满返回true,否则返回false
     */
    boolean isFull();
}

接口实现类

import java.util.Iterator;

public class ArrayQueue3<E> implements Queue<E>,Iterable<E> {
    private final E[] array;
    // head tail是两个不断递增的整数
    private int head = 0;
    private int tail = 0;

    @SuppressWarnings("all")
    public ArrayQueue3(int capacity) {
        // 初始化数组
        array = (E[]) new Object[capacity];
    }

    // 从队列尾部加入元素
    @Override
    public boolean offer(E e) {
        // 判满
        if(isFull()){
            return false;
        }
        array[tail % array.length] = e;
        tail ++;
        return true;
    }
    
    // 从队列头部移除元素
    @Override
    public E poll() {
        if (isEmpty()){
            return null;
        }
        // 找到索引位置
        E e = array[head % array.length];
        head ++;
        return e;
    }

    // 获取队列头部元素值
    @Override
    public E peek() {
        if (isEmpty()){
            return null;
        }
        return array[head % array.length];
    }

    @Override
    public boolean isEmpty() {
        return head == tail;
    }

    @Override
    public boolean isFull() {
        return tail - head == array.length;
    }

    @Override
    public Iterator<E> iterator() {
        return new Iterator<E>() {
            int cursor = head;
            @Override
            public boolean hasNext() {
                return cursor != tail;
            }

            @Override
            public E next() {
                E e = array[cursor % array.length];
                cursor++;
                return e;
            }
        };
    }
}

测试类 

import org.junit.Test;

import java.util.List;

import static org.junit.jupiter.api.Assertions.*;
import static org.junit.jupiter.api.Assertions.assertIterableEquals;

public class TestArrayQueue3 {
    // 向队列尾部插入值
    @Test
    public void offer() {
        ArrayQueue3<Integer> queue = new ArrayQueue3<>(5);
        queue.offer(1);
        queue.offer(2);
        queue.offer(3);
        queue.offer(4);
        queue.offer(5);
        assertIterableEquals(List.of(1, 2, 3, 4, 5), queue);
    }

    // 从队列头获取值,不移除
    @Test
    public void peek(){
        ArrayQueue3<Integer> queue = new ArrayQueue3<>(5);
        assertNull(queue.peek());
        queue.offer(1);
        assertEquals(1,queue.peek());
        queue.offer(2);
        assertEquals(1,queue.peek());
        queue.offer(3);
        assertEquals(1,queue.peek());
    }

    // 从队头获取值,并移除
    @Test
    public void poll() {
        ArrayQueue3<Integer> queue = new ArrayQueue3<>(5);
        queue.offer(1);
        queue.offer(2);
        queue.offer(3);
        queue.offer(4);
        queue.offer(5);

        assertEquals(1,queue.poll());
        assertEquals(2,queue.poll());
        assertEquals(3,queue.poll());
        assertEquals(4,queue.poll());
        assertEquals(5,queue.poll());
        assertNull(queue.poll());
    }

    // 向有限队列头部加入元素
    @Test
    public void offerLimit(){
        ArrayQueue3<Integer> queue = new ArrayQueue3<>(3);
        queue.offer(1);
        queue.offer(2);
        queue.offer(3);
        queue.offer(4);
        queue.offer(5);
        assertIterableEquals(List.of(1, 2, 3), queue);
    }
}

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

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

相关文章

C语言 | Leetcode C语言题解之第440题字典序的第K小数字

题目&#xff1a; 题解&#xff1a; #define MIN(x, y) ((x) < (y) ? (x) : (y))int getSteps(int curr, long n) {int steps 0;long first curr;long last curr;while (first < n) {steps MIN(last, n) - first 1;first first * 10;last last * 10 9;}return …

WMware安装WMware Tools(Linux~Ubuntu)

1、这里终端里面输入sudo apt upgrade用于更新最新的包 sudo apt upgrade 2、安装 open-vm-tools-desktop 包&#xff0c; Ps&#xff1a;这里是以为我已经安装好了。 udo apt install open-vm-tools-desktop -y3、最后重启就大功告成了 reboot 4、测试是否成功&#xff1a…

翻译器在线翻译:开启多语言交流新时代

随着国际交流、商务合作、文化交融以及互联网的飞速发展&#xff0c;人们对于跨越语言鸿沟的需求日益迫切。翻译工具成为了我们必备的一个工具&#xff0c;这篇文章我们一起来探讨一些好用的翻译器在线翻译工具吧。 1.在线福昕翻译 链接直达>>https://fanyi.pdf365.cn/…

[贪心+数学/数学+位运算] 两种方法O(1)解决 消减整数

标题&#xff1a;[贪心数学/数学位运算] 两种方法O(1)解决 消减整数 个人主页水墨不写bug 目录 一、题目&#xff1a;消减整数(Newcoder) 二、题目分析 1.理解题意&#xff1a; 2.解决问题 解法详解一&#xff1a;贪心数学 解法一参考代码&#xff1a; 解法详解二&#xf…

【RabbitMQ——具体使用场景】

1. 异步 1.1 同步异步的问题&#xff08;串行&#xff09; 串行方式&#xff1a;将订单信息写入数据库成功后&#xff0c;发送注册邮件&#xff0c;再发送注册短信。以上三个任务全部完成后&#xff0c;返回给客户端 public void makeOrder(){// 1 :保存订单 orderService.…

电脑退域或切换系统账号后系统黑屏

之前加入域时迁移了账号系统&#xff0c;导致退域后本地账号系统没了东西黑屏但能看到鼠标。也登不了域账号了一顿慌张&#xff08;操作如下&#xff09; 解决&#xff1a;又加回了域哈哈哈 重启电脑按F8进不去安全模式&#xff0c;找不到触发时间... winr打开运行&#xff0c;…

什么是托管安全信息和事件管理 SIEM?

什么是 SIEM&#xff1f; 安全信息和事件管理 ( SIEM ) 解决方案最初是一种集中式日志聚合解决方案。SIEM 解决方案会从整个组织网络中的系统收集日志数据&#xff0c;使组织能够从单一集中位置监控其网络。 随着时间的推移&#xff0c;SIEM解决方案已发展成为一个完整的威胁…

Jenkins简介;Jenkins安装

一&#xff0c;Jenkins简介 1、什么是Jenkins Jenkins是一个开源软件项目&#xff0c;是基于Java开发的一种持续集成工具&#xff0c;用于监控持续重复的工作&#xff0c;旨在提供一个开放易用的软件平台&#xff0c;使软件项目可以进行持续集成。 2、Jenkins的作用 持续的软…

【Golang】(推荐项目)Go后端工程项目

Go后端工程项目 在这个基于项目的课程中&#xff0c;我们将从头开始用 Go 构建一个完整的 REST API。 本次项目将从构建一个简单的 TCP 服务器开始&#xff0c;目标是探索 Go 中的 net/http 包。本项目的目标是获得构建和推理一般后端系统的基础知识。 为什么推荐这个项目&am…

操作台厂家如何设计工作台面才能让企业高效办公?

在快节奏的现代商业环境中&#xff0c;高效办公已成为企业竞争力的重要体现。嘉德立作为一家专注设计操作台厂家&#xff0c;很明确的告诉大家设计一款既能提升工作效率&#xff0c;又能兼顾员工舒适度的工作台面&#xff0c;是赢得市场的关键。那么&#xff0c;如何巧妙地设计…

【LLM】 TinyAgent 构建指南

文章目录 TinyAgent 构建指南项目概述实现步骤步骤一&#xff1a;模型构建步骤二&#xff1a;工具构建步骤三&#xff1a;Agent 构建步骤四&#xff1a;运行 Agent 结论参考文献学习心得 TinyAgent 构建指南 项目地址&#xff1a;https://github.com/datawhalechina/tiny-univ…

详解位示图计算方法、代码

位示图 位示图的核心思想计算过程与位操作假设问题场景&#xff1a; 实际操作与计算&#xff1a;1. 位示图的初始化2. 设置某一位&#xff08;标记资源占用&#xff09;3. 清除某一位&#xff08;释放资源&#xff09;4. 查询某一位&#xff08;检查资源状态&#xff09; 示例问…

【2米/8米光学卫星】

2米/8米光学卫星 2米/8米光学卫星&#xff0c;通常指的是GF-1 B、C、D卫星&#xff0c;这是我国民用空间基础设施发展规划中的首个民用高分辨率光学陆地业务星座&#xff0c;也是自然资源部组建后发射的首批业务卫星。以下是对该卫星的详细介绍&#xff1a; 一、基本信息 发…

k8s 分布式存储平台 -- Longhorn

文章目录 一、什么是 Longhorn二、架构设计1、工作原理2、工作流程3、基于微服务设计的优势 三、安装1、安装要求2、使用 Longhorn 命令行工具&#xff08;验证方式一&#xff09;3、使用环境检查脚本&#xff08;验证方式之二&#xff09;3.1、安装 jq3.2、运行脚本 4、安装 o…

AI会议时代:企业如何搭上快车?

“我 们认为&#xff0c;AI绝不仅是会议的辅助工具&#xff0c;而更会是重塑会议流程的关键力量。通过AI的个性化定制、大规模支持、智能分析这些技术&#xff0c;AI会议将大大提升会议的智能化与高效性&#xff0c;进而成为企业数字化转型的核心驱动力。” 作者|斗斗 编辑…

QTreeview model过滤

QTreeview model数据过滤&#xff1a;大小写区分&#xff0c;对列过滤&#xff0c;对子对象过滤 示例&#xff1a; 需要自定义QSortFilterProxyModel, //自定义过滤model mProxyModel new TreeFilterProxyModel(this); //添加treeview当前model mProxyModel->setSource…

【源码+文档+调试讲解】学生选课系统Python

摘 要 学生选课系统采用B/S架构&#xff0c;数据库是MySQL。网站的搭建与开发采用了先进的Python进行编写&#xff0c;使用了Django框架。该系统从三个对象&#xff1a;由管理员和学生、教师来对系统进行设计构建。主要功能包括&#xff1a;个人信息修改&#xff0c;对学生、教…

Brave编译指南2024 MacOS篇-获取源码(三)

引言 在上一篇文章中,我们介绍了Brave浏览器的基本特性,以及编译Brave所需的系统要求和推荐工具。现在,我们将进入编译过程的第一个实际步骤:获取Brave的源代码。这一步骤对于后续的编译和开发工作至关重要。 1. Brave源码的获取途径 Brave的源码托管在GitHub上,任何人都可以…

YOLO格式数据集转为COCO数据集(简单粗暴)

最近需要用的coco格式的数据集&#xff0c;但是在网上找的很多 毕竟麻烦&#xff0c;简单记录一下&#xff01; 1、调整目录结构&#xff08;以GC10-DET数据集为例&#xff09; YOLO格式数据集目录结构如下&#xff1a; 简单来说就是images文件夹里面有train、val、test三个文…

OJ在线评测系统 在Linux虚拟机搭建Docker 概念 入门 安装

Docker的基本概念 为什么要用docker容器技术 为了提升系统的安全性 把不同的程序和宿主机进行隔离 使得某个程序 应用的执行不会影响到系统本身 docker技术可以实现程序和宿主机的隔离 容器可以理解成对一系列应用程序、服务和环境的封装 从而把程序运行在一个隔离的 封闭…