集合及数据结构第十节(下)————常用接口介绍、堆的应用和java对象的比较

news2024/11/14 20:45:05

系列文章目录

集合及数据结构第十节(下)————常用接口介绍和堆的应用

常用接口介绍和堆的应用

  1. PriorityQueue的特性
  2. .PriorityQueue常用接口介绍
  3. top-k问题
  4. 堆排序
  5. PriorityQueue中插入对象
  6. 元素的比较
  7. .对象的比较
  8. .集合框架中PriorityQueue的比较方式

文章目录

  • 系列文章目录
    • 集合及数据结构第十节(下)————常用接口介绍和堆的应用
  • 一、常用接口介绍
    • 1.PriorityQueue的特性
    • 2.PriorityQueue常用接口介绍
      • 1. 优先级队列的构造
      • 2. 插入/删除/获取优先级最高的元素
  • 二、堆的应用
    • 1. top-k问题
      • 方法一:
      • 方法二(优化)
    • 2.堆排序
  • 三、java对象的比较
    • 1.PriorityQueue中插入对象
    • 2.元素的比较
      • 1. 基本类型的比较
      • 2. 对象比较的问题
    • 3.对象的比较( * *
      • 1. 覆写基类的equals
        • 注意:
      • 2.基于Comparble接口类的比较
      • 3. 基于比较器比较
      • 4 .三种方式对比
    • 4.集合框架中PriorityQueue的比较方式


一、常用接口介绍

1.PriorityQueue的特性

Java集合框架中提供了PriorityQueuePriorityBlockingQueue两种类型的优先级队列,PriorityQueue是线程不安全的PriorityBlockingQueue是线程安全的,所以主要介绍PriorityQueue

关于PriorityQueue的使用要注意:

  1. 使用时必须导入PriorityQueue所在的包,即:
import java.util.PriorityQueue;
  1. PriorityQueue中放置的元素必须要能够比较大小,不能插入无法比较大小的对象,否则会抛出ClassCastException异常

  2. 不能插入null对象,否则会抛出NullPointerException

  3. 没有容量限制,可以插入任意多个元素,其内部可以自动扩容

  4. 插入和删除元素的时间复杂度为
    在这里插入图片描述

  5. PriorityQueue底层使用了堆数据结构

  6. PriorityQueue默认情况下是小堆—即每次获取到的元素都是最小的元素

2.PriorityQueue常用接口介绍

1. 优先级队列的构造

此处只是列出了PriorityQueue中常见的几种构造方式
在这里插入图片描述

 public static void main(String[] args) {
        // 创建一个空的优先级队列,底层默认容量是11
        PriorityQueue<Integer> q1 = new PriorityQueue<>();
// 创建一个空的优先级队列,底层的容量为initialCapacity
        PriorityQueue<Integer> q2 = new PriorityQueue<>(100);
        ArrayList<Integer> list = new ArrayList<>();
        list.add(4);
        list.add(3);
        list.add(2);
        list.add(1);
// 用ArrayList对象来构造一个优先级队列的对象
// q3中已经包含了三个元素
        PriorityQueue<Integer> q3 = new PriorityQueue<>(list);
        System.out.println(q3.size());
        System.out.println(q3.peek());
    }

在这里插入图片描述

注意:默认情况下,PriorityQueue队列是小堆

    public static void main(String[] args) {
        // 创建一个空的优先级队列,底层默认容量是11
        PriorityQueue<Integer> priorityQueue = new PriorityQueue<>();//实例化一个PriorityQueue对象后,默认是一个小根堆
        priorityQueue.offer(1);
        priorityQueue.offer(2);
        priorityQueue.offer(3);
        priorityQueue.offer(4);
        priorityQueue.offer(5);

        System.out.println(priorityQueue.peek());
    }

在这里插入图片描述
如果需要大堆需要用户提供比较器:

 class Imp implements Comparator<Integer>{

        @Override
        public int compare(Integer o1, Integer o2) {
            return o2.compareTo(o1);//大根堆
        }
    }
public static void main(String[] args) {
        Imp imp = new Imp();
        PriorityQueue<Integer> priorityQueue = new PriorityQueue<>(imp);
        priorityQueue.offer(6);
        priorityQueue.offer(2);
        priorityQueue.offer(3);
        priorityQueue.offer(4);
        priorityQueue.offer(1);

        System.out.println(priorityQueue.poll());
        System.out.println(priorityQueue.peek());
    }

在这里插入图片描述
此时创建出来的就是一个大堆

2. 插入/删除/获取优先级最高的元素

函数名功能介绍
boolean offer(E e)插入元素e,插入成功返回true,如果e对象为空,抛出NullPointerException异常,时间复杂度 ,注意:空间不够时候会进行扩容
E peek()获取优先级最高的元素,如果优先级队列为空,返回null
E poll()移除优先级最高的元素并返回,如果优先级队列为空,返回null
int size()获取有效元素的个数
void clear()清空
boolean isEmpty()检测优先级队列是否为空,空返回true
public static void main(String[] args) {
        int[] arr = {4,1,9,2,8,0,7,3,6,5};
// 一般在创建优先级队列对象时,如果知道元素个数,建议就直接将底层容量给好
// 否则在插入时需要不多的扩容
// 扩容机制:开辟更大的空间,拷贝元素,这样效率会比较低
        PriorityQueue<Integer> q = new PriorityQueue<>(arr.length);
        for (int e: arr) {
            q.offer(e);
        }
        System.out.println(q.size()); // 打印优先级队列中有效元素个数
        System.out.println(q.peek()); // 获取优先级最高的元素
// 从优先级队列中删除两个元素之和,再次获取优先级最高的元素
        q.poll();
        q.poll();
        System.out.println(q.size()); // 打印优先级队列中有效元素个数
        System.out.println(q.peek()); // 获取优先级最高的元素
        q.offer(0);
        System.out.println(q.peek()); // 获取优先级最高的元素
// 将优先级队列中的有效元素删除掉,检测其是否为空
        q.clear();
        if(q.isEmpty()){
            System.out.println("优先级队列已经为空!!!");
        } else{
            System.out.println("优先级队列不为空");
        }
    }

在这里插入图片描述
注意:以下是JDK 1.8中,PriorityQueue的扩容方式:

private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
private void grow(int minCapacity) {
	int oldCapacity = queue.length;
	// Double size if small; else grow by 50%
	int newCapacity = oldCapacity + ((oldCapacity < 64) ?
				(oldCapacity + 2) :
				(oldCapacity >> 1));//(oldCapacity + 2) 是二倍扩容
				//(oldCapacity >> 1))是1.5倍扩容
	// overflow-conscious code
	if (newCapacity - MAX_ARRAY_SIZE > 0)
		newCapacity = hugeCapacity(minCapacity);
	queue = Arrays.copyOf(queue, newCapacity);
}
private static int hugeCapacity(int minCapacity) {
	if (minCapacity < 0) // overflow
		throw new OutOfMemoryError();
	return (minCapacity > MAX_ARRAY_SIZE) ?
		Integer.MAX_VALUE :
		MAX_ARRAY_SIZE;
}

优先级队列的扩容说明:

  • 如果容量小于64时,是按照oldCapacity的2倍方式扩容的
  • 如果容量大于等于64,是按照oldCapacity的1.5倍方式扩容的
  • 如果容量超过MAX_ARRAY_SIZE,按照MAX_ARRAY_SIZE来进行扩容

二、堆的应用

1. top-k问题

top-k问题:最大或者最小的前k个数据

设计一个算法,找出数组中最小的k个数。以任意顺序返回这k个数均可。

方法一:

示例:

输入: arr = [1,3,5,7,2,4,6,8], k = 4
输出: [1,2,3,4]

思路:

  1. 整体建立一个小根堆
  2. 将堆顶元素出堆,出看、次就找到了最小的k个数
   public int[] smallestK(int[] arr, int k) {
        if (null == arr || k <= 0) {//当数组为空,或者k小于等于0时,不能进行查找
            return new int[0];
        }
        PriorityQueue<Integer> priorityQueue = new PriorityQueue<>();
        //相当于是以向上调整的方式建立小根堆时间复杂度是:O(n*log2n)
        for (int i = 0; i < arr.length; i++) {
            priorityQueue.offer(arr[i]);
        }
        // 将优先级队列的前k个元素放到数组中
        int[] ret = new int[k];

        //时间复杂度:k*log2n
        for(int i = 0; i < k; ++i){
            ret[i] = priorityQueue.poll();
        }
        return ret;
    }

该解法只是PriorityQueue的简单使用,并不是topK最好的做法

方法二(优化)

TOP-K问题:即求数据集合中前K个最大的元素或者最小的元素,一般情况下数据量都比较大。
对于Top-K问题,能想到的最简单直接的方式就是排序,但是:如果数据量非常大,排序就不太可取了(可能数据都不能一下子全部加载到内存中)。最佳的方式就是用堆来解决,基本思路如下:

  1. 用数据集合中前K个元素来建堆
  • 前k个最大的元素,则建小堆
  • 前k个最小的元素,则建大堆
  1. 用剩余的N-K个元素依次与堆顶元素来比较,不满足则替换堆顶元素
    将剩余N-K个元素依次与堆顶元素比完之后,堆中剩余的K个元素就是所求的前K个最小或者最大的元素。
class Imp implements Comparator<Integer>{

        @Override
        public int compare(Integer o1, Integer o2) {
            return o2.compareTo(o1);//大根堆
        }
    }
   public int[] smallestK(int[] arr, int k) {//整体的时间复杂度是K*logK + N*logK - K*logK = N * logK
   if (null == arr || k <= 0) {//当数组为空,或者k小于等于0时,不能进行查找
            return new int[0];
        }
        /*PriorityQueue<Integer> priorityQueue = new PriorityQueue<>(new  Imp());*/
            PriorityQueue<Integer> priorityQueue = new PriorityQueue<>(new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return o2.compareTo(o1);//大根堆
            }
        });//匿名内部类的写法
        //O(k * log k)
        for (int i = 0; i < k; i++) {//用数据集合中前K个元素来建堆
            priorityQueue.offer(arr[i]);
            
        }
        //O(N - k) *logK
        for (int i = k; i < arr.length; i++) {//从k + 1个元素开始,将剩下的元素1与堆顶元素进行比较
            int top = priorityQueue.peek();//拿到堆顶元素
            if (top > arr[i]){
                priorityQueue.poll();
                priorityQueue.offer(arr[i]);
            }
        }
        // 将优先级队列的前k个元素放到数组中
        int[] ret = new int[k];
        //时间复杂度:k*log2n,这个地方不能算是topK的复杂度,这个地方是这里整理数据
        for(int i = 0; i < k; ++i){
            ret[i] = priorityQueue.poll();
        }
        return ret;
    }
}

2.堆排序

堆排序即利用堆的思想来进行排序,总共分为两个步骤:

  1. 建堆
  • 升序:建大堆
  • 降序:建小堆
  1. 利用堆删除思想来进行排序

建堆和堆删除中都用到了向下调整,因此掌握了向下调整,就可以完成堆排序
在这里插入图片描述
堆排序代码实现:

public class TestHeap {
    private  int[] elem;//用来存完全二叉树的数组
    public int usedSize;//用来记录当前堆中有效的数据个数

    public TestHeap(){//构造方法
        this.elem = new  int[10];//初始化数组大小为10
    }

    public void initElem(int[] array){//初始化elem数组
        for (int i = 0; i < array.length; i++) {
            elem[i] = array[i];
            usedSize++;//拷贝一个有效数据加1
        }
    }

    public void createHeap(){//创建大根堆
        //usedSize - 1 -->len   //usedSize - 1 - 1 -->拿到最后一个孩子节点(9)下标  //(usedSize - 1 - 1) / 2 -->拿到该孩子节点的父亲节点
        //如果i为0,则i表示的节点为根节点,否则i节点的双亲节点为 (i - 1)/2
        for (int parent = (usedSize - 1 - 1) / 2;parent >= 0;parent--){//确定每棵子树parent的下标
            siftDown(parent,usedSize);//每棵子树向下调整,传参为每颗子树的根和结束的位置
        }
    }

    public void siftDown(int parent,int len){//每棵子树向下调整
        int child = 2 * parent + 1;//parent节点的左孩子下标为2 * i + 1
        while (child < len){//当至少有左孩子时
            //在进行比较的时候要保证child + 1 < len,否则就会越界比较
            if (child + 1 < len && elem[child] < elem[child + 1]){//左孩子和右孩子进行比较,如果右孩子的值大,那么就记录一下它的下标
                child = child + 1;
            }
            //走完上述if语句,则child下标一定保存的是左右两个孩元素最大值的下标
            if (elem[child] > elem[parent]){//child下标的元素大于parent下标的元素,进行交换
                int temp = elem[child];
                elem[child] = elem[parent];
                elem[parent] = temp;
                parent = child;//parent指向child的位置
                child = 2 * parent + 1;//再接着对child的右孩子进行相同操作,parent节点的左孩子下标为2 * i + 1
            }else{
                break;//不需要比较了,直接break退出循环
            }
        }
    }
    public void swap(int child,int parent){
        int temp = elem[child];
        elem[child] = elem[parent];
        elem[parent] = temp;
    }

    //堆排序代码实现
    //时间复杂度是:N * logN
    public void heapSort(){
        int end = usedSize - 1;//记录最后一个元素为end
        while (end > 0){//当end大于堆顶元素下标0时
            swap(0,end);//交换0下标与end下标元素
            siftDown(0,end);//0 ~ end下标的元素向下调整,让堆顶元素成为比其他下标数大但小于end下标元素
            end--;//end向前移动一位确定下一个数
        }

    }
}

在这里插入图片描述

三、java对象的比较

1.PriorityQueue中插入对象

优先级队列在插入元素时有个要求:插入的元素不能是null或者元素之间必须要能够进行比较,为了简单起见,我们只是插入了Integer类型,那优先级队列中能否插入自定义类型对象呢?

    class Card {
        public int rank; // 数值
        public String suit; // 花色
        public Card(int rank, String suit) {
            this.rank = rank;
            this.suit = suit;
        }
    }
    public class TestPriorityQueue {
        public static void TestPriorityQueue()
        {
            PriorityQueue<Card> p = new PriorityQueue<>();
            p.offer(new Card(1, "♠"));
            p.offer(new Card(2, "♠"));
        }
        public static void main(String[] args) {
            TestPriorityQueue();
        }
    }

优先级队列底层使用堆,而向堆中插入元素时,为了满足堆的性质,必须要进行元素的比较,而此时Card是没有办法直接进行比较的,因此抛出异常
在这里插入图片描述

2.元素的比较

1. 基本类型的比较

在Java中,基本类型的对象可以直接比较大小

    public class TestCompare {
        public static void main(String[] args) {
            int a = 10;
            int b = 20;
            System.out.println(a > b);
            System.out.println(a < b);
            System.out.println(a == b);
            char c1 = 'A';
            char c2 = 'B';
            System.out.println(c1 > c2);
            System.out.println(c1 < c2);
            System.out.println(c1 == c2);
            boolean b1 = true;
            boolean b2 = false;
            System.out.println(b1 == b2);
            System.out.println(b1 != b2);
        }
    }

2. 对象比较的问题

class Card {
        public int rank; // 数值
        public String suit; // 花色
        public Card(int rank, String suit) {
            this.rank = rank;
            this.suit = suit;
        }
    }
        public void main(String[] args) {
            Card c1 = new Card(1, "♠");
            Card c2 = new Card(2, "♠");
            Card c3 = c1;
//System.out.println(c1 > c2); // 编译报错
            System.out.println(c1 == c2); // 编译成功 ----> 打印false,因为c1和c2指向的是不同对象
//System.out.println(c1 < c2); // 编译报错
            System.out.println(c1 == c3); // 编译成功 ----> 打印true,因为c1和c3指向的是同一个对象
        }
    

c1、c2和c3分别是Card类型的引用变量,上述代码在比较编译时:
c1 > c2 编译失败
c1== c2 编译成功
c1 < c2 编译失败
从编译结果可以看出,Java中引用类型的变量不能直接按照 > 或者 < 方式进行比较。 那为什么 == 可以比较?
因为:对于用户实现自定义类型,都默认继承自Object类,而Object类中提供了equal方法,而 == 默认情况下调用的就是equal方法,但是该方法的比较规则是:没有比较引用变量引用对象的内容,而是直接比较引用变量的地址,但有些情况下该种比较就不符合题意

// Object中equal的实现,可以看到:直接比较的是两个引用变量的地址
public boolean equals(Object obj) {
	return (this == obj);
}

3.对象的比较( * *

有些情况下,需要比较的是对象中的内容,比如:向优先级队列中插入某个对象时,需要对按照对象中内容来调整堆,那该如何处理呢

1. 覆写基类的equals

  public class Card {
        public int rank; // 数值
        public String suit; // 花色

        public Card(int rank, String suit) {
            this.rank = rank;
            this.suit = suit;
        }

        @
                Override
        public boolean equals(Object o) {
// 自己和自己比较
            if (this == o) {
                return true;
            }
            // o如果是null对象,或者o不是Card的子类
            if (o == null || !(o instanceof Card)) {
                return false;
            }
            // 注意基本类型可以直接比较,但引用类型最好调用其equal方法
            Card c = (Card) o;
            return rank == c.rank
                    && suit.equals(c.suit);
        }
    }
注意:

一般覆写 equals 的套路就是上面演示的

  1. 如果指向同一个对象,返回 true
  2. 如果传入的为 null,返回 false
  3. 如果传入的对象类型不是 Card,返回 false
  4. 按照类的实现目标完成比较,例如这里只要花色和数值一样,就认为是相同的牌
  5. 注意下调用其他引用类型的比较也需要 equals,例如这里的 suit 的比较
    覆写基类equal的方式虽然可以比较,但缺陷是:equal只能按照相等进行比较,不能按照大于、小于的方式进行比较

2.基于Comparble接口类的比较

Comparble是JDK提供的泛型的比较接口类,源码实现具体如下:

public interface Comparable<E> {
	// 返回值:
	// < 0: 表示 this 指向的对象小于 o 指向的对象
	// == 0: 表示 this 指向的对象等于 o 指向的对象
	// > 0: 表示 this 指向的对象大于 o 指向的对象
	int compareTo(E o);
}

对用用户自定义类型,如果要想按照大小与方式进行比较时:在定义类时,实现Comparble接口即可,然后在类中重写compareTo方法

    public class Card implements Comparable<Card> {
        public int rank; // 数值
        public String suit; // 花色
        public Card(int rank, String suit) {
            this.rank = rank;
            this.suit = suit;
        }
        // 根据数值比较,不管花色
        // 这里我们认为 null 是最小的
        @Override
        public int compareTo(Card o) {
            if (o == null) {
                return 1;
            }
            return rank - o.rank;
        }
        public static void main(String[] args){
            Card p = new Card(1, "♠");
            Card q = new Card(2, "♠");
            Card o = new Card(1, "♠");
            System.out.println(p.compareTo(o)); // == 0,表示牌相等
            System.out.println(p.compareTo(q)); // < 0,表示 p 比较小
            System.out.println(q.compareTo(p)); // > 0,表示 q 比较大
        }
    }

Compareble是java.lang中的接口类,可以直接使用

3. 基于比较器比较

按照比较器方式进行比较,具体步骤如下:

  • 用户自定义比较器类,实现Comparator接口
    public interface Comparator<T> {
        // 返回值:
// < 0: 表示 o1 指向的对象小于 o2 指向的对象
// == 0: 表示 o1 指向的对象等于 o2 指向的对象
// > 0: 表示 o1 指向的对象等于 o2 指向的对象
        int compare(T o1, T o2);
    }

注意:区分Comparable和Comparator

  • 覆写Comparator中的compare方法
 import java.util.Comparator;
    class Card {
        public int rank; // 数值
        public String suit; // 花色
        public Card(int rank, String suit) {
            this.rank = rank;
            this.suit = suit;
        }
    }
    class CardComparator implements Comparator<Card> {
        // 根据数值比较,不管花色
// 这里我们认为 null 是最小的
        @Override
        public int compare(Card o1, Card o2) {
            if (o1 == o2) {
                return 0;
            } if
            (o1 == null) {
                return -1;
            }
            if (o2 == null) {
                return 1;
            } 
            return o1.rank - o2.rank;
        }
        public static void main(String[] args){
            Card p = new Card(1, "♠");
            Card q = new Card(2, "♠");
            Card o = new Card(1, "♠");
// 定义比较器对象
            CardComparator cmptor = new CardComparator();
// 使用比较器对象进行比较
            System.out.println(cmptor.compare(p, o)); // == 0,表示牌相等
            System.out.println(cmptor.compare(p, q)); // < 0,表示 p 比较小
            System.out.println(cmptor.compare(q, p)); // > 0,表示 q 比较大
        }
    }

注意:Comparator是java.util 包中的泛型接口类,使用时必须导入对应的包

4 .三种方式对比

覆写的方法说明
Object.equals因为所有类都是继承自 Object 的,所以直接覆写即可,不过只能比较相等与否
Comparable.compareTo需要手动实现接口,侵入性比较强,但一旦实现,每次用该类都有顺序,属于内部顺序
Comparator.compare需要实现一个比较器对象,对待比较类的侵入性弱,但对算法代码实现侵入性强

4.集合框架中PriorityQueue的比较方式

集合框架中的PriorityQueue底层使用堆结构,因此其内部的元素必须要能够比大小,PriorityQueue采用了:
Comparble和Comparator两种方式。

  1. Comparble是默认的内部比较方式,如果用户插入自定义类型对象时,该类对象必须要实现Comparble接口,并覆写compareTo方法
  2. 用户也可以选择使用比较器对象,如果用户插入自定义类型对象时,必须要提供一个比较器类,让该类实现Comparator接口并覆写comp
    // JDK中PriorityQueue的实现:
    public class PriorityQueue<E> extends AbstractQueue<E>
            implements java.io.Serializable {
        // ...
// 默认容量
        private static final int DEFAULT_INITIAL_CAPACITY = 11;
        // 内部定义的比较器对象,用来接收用户实例化PriorityQueue对象时提供的比较器对象
        private final Comparator<? super E> comparator;
        // 用户如果没有提供比较器对象,使用默认的内部比较,将comparator置为null
        public PriorityQueue() {
            this(DEFAULT_INITIAL_CAPACITY, null);
        }
        // 如果用户提供了比较器,采用用户提供的比较器进行比较
        public PriorityQueue(int initialCapacity, Comparator<? super E> comparator) {
// Note: This restriction of at least one is not actually needed,
// but continues for 1.5 compatibility
            if (initialCapacity < 1)
                throw new IllegalArgumentException();
            this.queue = new Object[initialCapacity];
            this.comparator = comparator;
        }
        // ...
        // 向上调整:
// 如果用户没有提供比较器对象,采用Comparable进行比较
// 否则使用用户提供的比较器对象进行比较
        private void siftUp(int k, E x) {
            if (comparator != null)
                siftUpUsingComparator(k, x);
            else
                siftUpComparable(k, x);
        }
        // 使用Comparable
        @SuppressWarnings("unchecked")
        private void siftUpComparable(int k, E x) {
            Comparable<? super E> key = (Comparable<? super E>) x;
            while (k > 0) {
                int parent = (k - 1) >>> 1;
                Object e = queue[parent];
                if (key.compareTo((E) e) >= 0)
                    break;
                queue[k] = e;
                k = parent;
            }
            queue[k] = key;
        }
        // 使用用户提供的比较器对象进行比较
        @SuppressWarnings("unchecked")
        private void siftUpUsingComparator(int k, E x) {

            while (k > 0) {
                int parent = (k - 1) >>> 1;
                Object e = queue[parent];
                if (comparator.compare(x, (E) e) >= 0)
                    break;
                queue[k] = e;
                k = parent;
            }
            queue[k] = x;
        }
    }

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

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

相关文章

《系统架构设计师教程(第2版)》第15章-面向服务架构设计理论与实践-04-SOA设计

文章目录 1. SOA设计的标准要求1.1 文档标准1.2 通信协议标准1.3 应用程序统一登记与集成1.4 服务质量 (QoS)1.4.1 可靠性1.4.2 安全性1.4.3 策略1.4.4 控制1.4.5 管理 2. SOA的设计原则 1. SOA设计的标准要求 OASIS Organization for the Advancement of Structured Informati…

RISCV汇编编程讲解

第一章 引言 为什么要讲riscv&#xff1f; riscv的特点&#xff1a; -诞生于顶尖学术机构&#xff1a;诞生于加州大学伯克利分校的体系结构研究院。吸引了大批的顶尖企业参与&#xff08;e.g. 谷歌、华为、高通、阿里巴巴为rsicv的发展提供了大量的资金支持和贡献了技术和人才…

【计算机网络】名词解释--网络专有名词详解(更新)

在网络通信中&#xff0c;有许多专业术语和概念&#xff0c;它们共同构成了网络通信的基础。以下是一些常见的网络术语及其定义和相互之间的关系&#xff1a; 一、网络基础 1.1 电路交换&#xff1a;电路交换是一种在数据传输前建立专用通信路径的通信方式。在通信开始前&…

RAG 技术原理

目录 RAG 技术原理背景和概念实现步骤1. ChatGPT/GLM 等大语言模型的调用2. 读取知识库数据3. 文本索引与答案检索4. 文本嵌入与向量检索5. 文本多路召回与重排序6. 文本问答Promopt优化 原创链接 RAG 技术原理 背景和概念 在自然语言处理领域&#xff0c;大型语言模型&#x…

使用 C 语言实现字符走迷宫 DFS算法应用

使用 C 语言实现字符走迷宫 DFS算法应用 迷宫问题是一个经典的编程问题&#xff0c;通常用于算法训练。我们将通过使用 C 语言来实现一个字符迷宫的求解&#xff0c;其中玩家可以控制字符在迷宫中移动&#xff0c;直到找到出口。 1. 问题描述 我们将设计一个二维迷宫&#xf…

Unity--AnimationCurve动画曲线设置

参考文章&#xff1a;https://blog.csdn.net/qq_20179331/article/details/131309128 打开Clip文件点击Curves选项&#xff0c;选中想要编辑的动作关键帧&#xff0c;右键选择Auto 这样动画就变成线性的了

爆改YOLOv8 |利用 iAFF迭代注意力改进C2f,高效涨点

1&#xff0c;本文介绍 iAFF的核心思想是通过细致的注意力机制优化特征融合&#xff0c;从而提升卷积神经网络的性能。它不仅解决了因尺度和语义不一致导致的特征融合问题&#xff0c;还引入了多尺度通道注意力模块&#xff0c;提供了一个统一且通用的特征融合方案。此外&…

二分查找算法:朴素二分+左右边界二分力扣实战应用

目录&#xff1a; 1、二分查找算法简介 2、算法原理及时间复杂度分析 2.1 朴素二分算法 3.2 查找左右边界的二分算法 3.2.1 查找左边界 3.2.2 查找右边界 3.3 时间复杂度分析 3、二分查找算法模版 3.1 朴素二分模版 3.2 查找左右边界的二分模版 4、算法应用【leetco…

企业收款码,自动统计职员绩效-微信支付商家版

一、企业收款码 在快节奏的商业世界中&#xff0c;效率与精准是企业成功的关键。微信支付商家版企业收款码&#xff0c;为你开启全新的绩效统计时代。 告别繁琐的传统统计方式&#xff0c;无需再耗费大量时间人工整理数据。企业收款码自动统计职员绩效&#xff0c;每一笔交易都…

Cortex-A7的GIC(通用中断控制器):中断处理状态机

0 资料 ARM Generic Interrupt Controller Architecture version 2.0 Architecture Specification1 中断处理状态机 1.1 中断处理状态说明及状态机转换图 说明&#xff1a; Inactive&#xff1a;未激活&#xff0c;中断无效。中断非挂起或非激活。 Pending&#xff1a;挂起&a…

iZotope Ozone 11 Advanced:专业音频制作与母带处理的巅峰之作

iZotope Ozone 11 Advanced是一款专为音频工程师、制作人和音乐人设计的顶级音频后期制作软件&#xff0c;无论是Mac还是Windows平台&#xff0c;都能为用户提供无与伦比的音频处理体验。该软件集成了最先进的人工智能技术和一系列精密的音频处理工具&#xff0c;让音频作品的最…

还在烦恼Cosplay论坛开发?探索PHP+Vue的完美解决方案!

&#x1f393; 作者&#xff1a;计算机毕设小月哥 | 软件开发专家 &#x1f5a5;️ 简介&#xff1a;8年计算机软件程序开发经验。精通Java、Python、微信小程序、安卓、大数据、PHP、.NET|C#、Golang等技术栈。 &#x1f6e0;️ 专业服务 &#x1f6e0;️ 需求定制化开发源码提…

STM32定时器PWM输出

STM32定时器PWM&#xff08;脉冲宽度调制&#xff09;输出原理&#xff0c;在使用固件库时&#xff0c;主要涉及定时器的配置以及PWM信号的生成。以下是对该原理的详细解释&#xff1a; 一、PWM基本概念 PWM&#xff08;Pulse Width Modulation&#xff09;是一种通过改变脉冲…

docker 容器内文件传到宿主机上

sudo docker cp 容器名&#xff1a;文件路径 宿主机路径 ylshy-Super-Server:~$ pwd /home/yl ylshy-Super-Server:~$ ^C ylshy-Super-Server:~$ sudo docker cp ylafl:/opt/live555/testProgs/rtsp.pcap /home/yl Successfully copied 4.61kB to /home/yl ylshy-Super-Server…

自适应学习率(Datawhale X 李宏毅苹果书 AI夏令营)

传统的梯度下降方法在优化过程中常常面临学习率设置不当的问题。固定的学习率在训练初期可能过大&#xff0c;导致模型训练不稳定&#xff0c;而在后期可能过小&#xff0c;导致训练速度缓慢。为了克服这些问题&#xff0c;自适应学习率方法应运而生。这些方法通过动态调整学习…

Django使用视图动态输出CSV以及PDF的操作详解例子解析

代码示例&#xff1a; 在Django中&#xff0c;使用视图动态输出CSV和PDF文件是一个常见的需求&#xff0c;可以通过Python标准库中的csv模块和reportLab库来实现。以下是一些详细的操作步骤和示例代码。 CSV文件的动态输出 首先&#xff0c;需要导入Python的csv模块&#xf…

JSP的九大内置对象及其作用详解

JSP的九大内置对象及其作用详解 1. request对象2. response对象3. pageContext对象4. session对象5. application对象6. out对象7. config对象8. page对象9. exception对象 &#x1f496;The Begin&#x1f496;点点关注&#xff0c;收藏不迷路&#x1f496; 在JSP&#xff08…

<数据集>骨折检测数据集<目标检测>

数据集格式&#xff1a;VOCYOLO格式 图片数量&#xff1a;2060张 标注数量(xml文件个数)&#xff1a;2060 标注数量(txt文件个数)&#xff1a;2060 标注类别数&#xff1a;7 标注类别名称&#xff1a;[elbow positive, shoulder fracture, fingers positive, wrist positi…

0818-0824面试题目和复习整理

根据面试问的问题整理一下 1. 并查集 int n 1005; // n根据题目中节点数量而定&#xff0c;一般比节点数量大一点就好 vector<int> father vector<int> (n, 0); // C里的一种数组结构// 并查集初始化 void init() {for (int i 0; i < n; i) {father[i] i;…

Kubernetes部署相关概念

本文封面由 凯楠&#x1f4f8;友情提供 Kubernetes部署相关概念概览 容器运行时&#xff08;container runtime&#xff09;&#xff1a; 是负责在计算机操作系统上创建、运行和管理容器的软件组件。它是整个容器化环境中的关键组成部分&#xff0c;与操作系统内核紧密交互&a…