【Java数据结构 -- List和ArrayList与顺序表】

news2024/9/17 8:44:45

List和ArrayList与顺序表

  • 一. List
    • 1.1 List介绍
    • 2.1 常见接口介绍
    • 3.1 List的使用
  • 二. ArrayList与顺序表
    • 1.线性表
    • 2.顺序表
      • 2.1 接口的实现
    • 3.ArrayList简介
    • 4. ArrayList使用
      • 4.1 ArrayList的构造
    • 4.2 ArrayList常见操作
    • 4.3 ArrayList的遍历
    • 4.4 ArrayList的扩容机制
    • 5. ArrayList的具体使用
      • 5.1 简单的洗牌算法
      • 5.2 杨辉三角的实现
    • 6 面试题

一. List

1.1 List介绍

在集合框架中,List是一个接口,继承Collection
Iterable <-- Collection <-- List

Collection也是一个接口,该接口中规范了后序容器中常用的一些方法,具体如下所示:
在这里插入图片描述
Iterable也是一个接口,表示实现该接口的类是可以逐个元素进行遍历的,具体如下:
在这里插入图片描述
站在数据结构的角度来看,List就是一个线性表,即n个具有相同类型元素的有限序列,在该序列上可以执行增删改查以及变量等操作

2.1 常见接口介绍

List中提供了很多方法,具体的常用方法如下:
方法 ---- 解释
boolean add(E e) ---- 尾插 e
void add(int index, E element) ---- 将 e 插入到 index 位置
boolean addAll(Collection<? extends E> c) ---- 尾插 c 中的元素
E remove(int index) ---- 删除 index 位置元素
boolean remove(Object o) ---- 删除遇到的第一个 o
E get(int index) ---- 获取下标 index 位置元素
E set(int index, E element) ---- 将下标 index 位置元素设置为 element
void clear() ---- 清空
boolean contains(Object o) ---- 判断 o 是否在线性表中
int indexOf(Object o) ---- 返回第一个 o 所在下标
int lastIndexOf(Object o) ---- 返回最后一个 o 的下标
List subList(int fromIndex, int toIndex) ---- 截取部分 list

3.1 List的使用

List是一个接口,并不是直接用来实例化
如果要使用的话必须先去实例化List的实现类,ArrayLsit和LinkedList都实现了List接口。

二. ArrayList与顺序表

1.线性表

线性表是n个具有相同特性的数据元素的有限序列。线性表是一种在实际中广泛使用的数据结构,常见的线性表:顺序表、链表、栈、队列等等。

线性表在逻辑上是线性结构,也就说是连续的一条直线。但是在物理结构上并不一定是连续的,线性表在物理上存储时,通常以数组和链式结构的形式存储
在这里插入图片描述

2.顺序表

顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储。在数组上完成数据的增删查改。

2.1 接口的实现

IList接口:

public interface IList {
    // 新增元素,默认在数组最后新增
    public void add(int data);
    // 在 pos 位置新增元素
    public void add(int pos, int data);
    // 判定是否包含某个元素
    public boolean contains(int toFind);
    // 查找某个元素对应的位置
    public int indexOf(int toFind);
    // 获取 pos 位置的元素
    public int get(int pos);
    // 给 pos 位置的元素设为 value
    public void set(int pos, int value);
    //删除第一次出现的关键字key
    public void remove(int toRemove);
    // 获取顺序表长度
    public int size();
    // 清空顺序表
    public void clear();
    // 打印顺序表,注意:该方法并不是顺序表中的方法,为了方便看测试结果给出的
    public void display();

    Boolean isFull();
    Boolean isEmpty();
}

实现ArrayList方法:

public class MyArrayList implements IList{
    public int[] elem;
    public int usedSize;
    public static final int DEFAULT_CAPACITY = 5;

    public MyArrayList() {
        elem = new int[DEFAULT_CAPACITY];
    }

    @Override
    public void display() {
        for (int i = 0; i < this.usedSize; i++) {
            System.out.println(elem[i]+" ");
        }
        System.out.println();
    }

    @Override
    public void add(int data) {
        // 判断是否满了 满了就要扩容
        if (isFull()) {
            elem = Arrays.copyOf(elem,elem.length*2);
        }
        this.elem[usedSize] = data;
        this.usedSize++;
    }

    @Override
    public Boolean isFull() {
        return this.usedSize == DEFAULT_CAPACITY;
    }

    @Override
    public void add(int pos, int data) {
        // pos位置的判断
        checkPosOfAdd(pos);
        if (isFull()) {
            elem = Arrays.copyOf(elem,elem.length*2);
        }
        for (int i = this.usedSize-1; i >= pos; i--) {
            this.elem[i+1] = elem[i];
        }
        this.elem[pos] = data;
        this.usedSize++;

        System.out.println();
    }

    private void checkPosOfAdd(int pos) {
        if (pos<0 || pos >this.usedSize) {
            throw new PosException("Pos位置为:"+ pos);
        }
    }

    @Override
    public boolean contains(int toFind) {
        for (int i = 0; i < this.usedSize; i++) {
            if (elem[i] == toFind){
                return true;
            }
        }
        return false;
    }

    @Override
    public int indexOf(int toFind) {
        for (int i = 0; i < this.usedSize; i++) {
            if (elem[i] == toFind) {
                return i;
            }
        }
        return -1;
    }

    // 获取pos位置的值
    @Override
    public int get(int pos) {
        // 判断pos位置
        checkPosOfGet(pos);

        // 为空
        if (isEmpty()) {
            throw new EmptyException("顺序表为空");
            //return -1;
        }
        return this.elem[pos];
    }

    public Boolean isEmpty() {
        return usedSize ==0;
    }


    private void checkPosOfGet(int pos){
        if (pos < 0 || pos >= this.usedSize) {
            throw new PosException("Pos位置不合法:"+pos);
        }
    }


    // 更新pos位置的值为value
    @Override
    public void set(int pos, int value) {
        checkPosOfGet(pos);
        if (isEmpty()) {
            System.out.println("顺序表为空");
        }
        this.elem[pos] = value;
    }

    // 删除toRemove这个值
    @Override
    public void remove(int toRemove) {
        if (isEmpty()) {
            throw new EmptyException("顺序表为空");
        }
        int index=indexOf(toRemove);
        for (int i = index; i < this.usedSize-1; i++) {
            this.elem[i] = this.elem[i+1];
        }
        this.usedSize--;
    }

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

    //清空顺序表  防止数据泄露
    @Override
    public void clear() {
        this.usedSize = 0;
    }
}

注意

  • 在定义了一个空顺序表的时候第一次add分配了默认的内存大小
  • 在扩容的时候是以1.5倍扩容
    Main测试:

    public static void main2(String[] args) {
/*        ArrayList<Integer> arrayList = new ArrayList<>();
        arrayList.add(10);
        arrayList.add(20);
        arrayList.add(30);

        arrayList.add(0,99);*/
        //第一次add的时候  分配了内存大小为10
        //扩容的时候 是1.5倍扩容


        ArrayList<Integer> arrayList1 = new ArrayList<>();
        arrayList1.add(10);
        arrayList1.add(20);
        arrayList1.add(30);

        // 传入的参数是E类型或者是E类型的子类
        ArrayList<Number> arrayList2 = new ArrayList<>(arrayList1);
        arrayList2.add(9999);
        System.out.println(arrayList2);
        //[10, 20, 30, 9999]

        //list 通过sublist截取后 指向的还是arrayList2所指向的内容 即list和arrayList2指向的内容一致
        // 所以修改list指向的内容就是 arrayList2的值也会变
        List<Number> list = arrayList2.subList(0,2);
        System.out.println(list);
        //[10, 20]

        System.out.println("=====");
        list.set(0,199);

        System.out.println(arrayList2);  //[199, 20, 30, 9999]
        System.out.println(list);       //[199, 20]



    }
    public static void main1(String[] args) {
        MyArrayList myArrayList = new MyArrayList();
        myArrayList.add(1);
        myArrayList.add(2);
        myArrayList.add(3);
        myArrayList.add(4);
        myArrayList.add(5);
        myArrayList.add(6);

        System.out.println(myArrayList.contains(3));
        System.out.println(myArrayList.indexOf(5));

        myArrayList.remove(3);
        myArrayList.display();
    }

3.ArrayList简介

在集合框架中,ArrayList是一个普通的类,实现了List接口,具体框架图如下:
在这里插入图片描述注意:

  1. ArrayList是以泛型方式实现的,使用时必须要先实例化
  2. ArrayList实现了RandomAccess接口,表明ArrayList支持随机访问
  3. ArrayList实现了Cloneable接口,表明ArrayList是可以clone的
  4. ArrayList实现了Serializable接口,表明ArrayList是支持序列化的
  5. 和Vector不同,ArrayList不是线程安全的,在单线程下可以使用,在多线程中可以选择Vector或者CopyOnWriteArrayList
  6. ArrayList底层是一段连续的空间,并且可以动态扩容,是一个动态类型的顺序表

4. ArrayList使用

4.1 ArrayList的构造

在这里插入图片描述
注意在这里的extends E 传入的是E类型或者是E的子类型

public static void main(String[] args) {
	// ArrayList创建,推荐写法
	// 构造一个空的列表
	List<Integer> list1 = new ArrayList<>();
	// 构造一个具有10个容量的列表
	List<Integer> list2 = new ArrayList<>(10);
	list2.add(1);
	list2.add(2);
	list2.add(3);
	// list2.add("hello"); // 编译失败,List<Integer>已经限定了,list2中只能存储整形元素
	// list3构造好之后,与list中的元素一致
	ArrayList<Integer> list3 = new ArrayList<>(list2);
	// 避免省略类型,否则:任意类型的元素都可以存放,使用时将是一场灾难
	List list4 = new ArrayList();
	list4.add("111");
	list4.add(100);
}

4.2 ArrayList常见操作

方法 ------ 解释
boolean add(E e) ------ 尾插 e
void add(int index, E element) ------ 将 e 插入到 index 位置
boolean addAll(Collection<? extends E> c) ------ 尾插 c 中的元素
E remove(int index) ------ 删除 index 位置元素
boolean remove(Object o) ------ 删除遇到的第一个 o
E get(int index) ------ 获取下标 index 位置元素
E set(int index, E element) ------ 将下标 index 位置元素设置为 element
void clear() ------ 清空
boolean contains(Object o) ------ 判断 o 是否在线性表中
int indexOf(Object o) ------ 返回第一个 o 所在下标
int lastIndexOf(Object o) ------ 返回最后一个 o 的下标
List subList(int fromIndex, int toIndex) ------ 截取部分 list

    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("JavaSE");
        list.add("JavaWeb");
        list.add("JavaEE");
        list.add("JVM");
        list.add("测试课程");
        System.out.println(list);

        // 获取list中有效元素个数
        System.out.println(list.size());

        // 获取和设置index位置上的元素,注意index必须介于[0, size)间
        System.out.println(list.get(1));

        list.set(1, "JavaWEB");
        System.out.println(list.get(1));

        // 在list的index位置插入指定元素,index及后续的元素统一往后搬移一个位置
        list.add(1, "Java数据结构");
        System.out.println(list);

        // 删除指定元素,找到了就删除,该元素之后的元素统一往前搬移一个位置
        list.remove("JVM");
        System.out.println(list);

        // 删除list中index位置上的元素,注意index不要超过list中有效元素个数,否则会抛出下标越界异常
        list.remove(list.size()-1);
        System.out.println(list);

        // 检测list中是否包含指定元素,包含返回true,否则返回false
        if(list.contains("测试课程")){
            list.add("测试课程");
        }

        // 查找指定元素第一次出现的位置:indexOf从前往后找,lastIndexOf从后往前找
        list.add("JavaSE");
        System.out.println(list.indexOf("JavaSE"));
        System.out.println(list.lastIndexOf("JavaSE"));

        // 使用list中[0, 4)之间的元素构成一个新的SubList返回,但是和ArrayList共用一个elementData数组
        List<String> ret = list.subList(0, 4);
        System.out.println(ret);

        list.clear();
        System.out.println(list.size());
    }

4.3 ArrayList的遍历

ArrayList 可以使用三方方式遍历:for循环+下标、foreach、使用迭代器

    public static void main(String[] args) {
        ArrayList<Integer> arrayList = new ArrayList<>();
        arrayList.add(10);
        arrayList.add(20);
        arrayList.add(30);

        //ArrayList的遍历
        //第一种遍历方式   重写了toString方法
        System.out.println(arrayList);

        //第二种遍历方式
        for (int i = 0; i < arrayList.size(); i++) {
            System.out.print(arrayList.get(i)+" ");
        }

        System.out.println();

        //3.for-each
        for (int x:arrayList) {
            System.out.print(x+" ");
        }
        System.out.println();

        // 4. 迭代器
        Iterator<Integer> it = arrayList.iterator();
        while (it.hasNext()) {
            System.out.print(it.next()+" ");
        }
        System.out.println();

        //5. ListIterator  是 Iterator的子类
        ListIterator<Integer> it2 = arrayList.listIterator();
        while (it2.hasNext()) {
            System.out.print(it2.next()+" ");
        }
        System.out.println();

        //6. 从后往前打印
        ListIterator<Integer> it3 = arrayList.listIterator();
        while (it2.hasPrevious()) {
            System.out.print(it2.previous()+" ");
        }
        System.out.println();
    }

4.4 ArrayList的扩容机制

ArrayList是一个动态类型的顺序表,即:在插入元素的过程中会自动扩容。
ArrayList源码:

Object[] elementData; // 存放元素的空间
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {}; // 默认空间
private static final int DEFAULT_CAPACITY = 10; // 默认容量大小
public boolean add(E e) {
	ensureCapacityInternal(size + 1); // Increments modCount!!
	elementData[size++] = e;
	return true;
}
private void ensureCapacityInternal(int minCapacity) {
	ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
}
private static int calculateCapacity(Object[] elementData, int minCapacity) {
	if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
	return Math.max(DEFAULT_CAPACITY, minCapacity);
	}
	return minCapacity;
}
private void ensureExplicitCapacity(int minCapacity) {
	modCount++;
	// overflow-conscious code
	if (minCapacity - elementData.length > 0)
	grow(minCapacity);
}
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
private void grow(int minCapacity) {
	// 获取旧空间大小
	int oldCapacity = elementData.length;
	// 预计按照1.5倍方式扩容
	int newCapacity = oldCapacity + (oldCapacity >> 1);
	// 如果用户需要扩容大小 超过 原空间1.5倍,按照用户所需大小扩容
	if (newCapacity - minCapacity < 0)
	newCapacity = minCapacity;
	// 如果需要扩容大小超过MAX_ARRAY_SIZE,重新计算容量大小
	if (newCapacity - MAX_ARRAY_SIZE > 0)
	newCapacity = hugeCapacity(minCapacity);
	// 调用copyOf扩容
	elementData = Arrays.copyOf(elementData, newCapacity);
}
private static int hugeCapacity(int minCapacity) {
	// 如果minCapacity小于0,抛出OutOfMemoryError异常
	if (minCapacity < 0)
	throw new OutOfMemoryError();
	return (minCapacity > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE : MAX_ARRAY_SIZE;
}

总结:

  1. 检测是否真正需要扩容,如果是调用grow准备扩容
  2. 预估需要库容的大小初步预估按照1.5倍大小扩容,如果用户所需大小超过预估1.5倍大小,则按照用户所需大小扩容,真正扩容之前检测是否能扩容成功,防止太大导致扩容失败
  3. 使用copyOf进行扩容

5. ArrayList的具体使用

5.1 简单的洗牌算法

Card:

public class Card {
    public String suit;
    public int num;

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

    @Override
    public String toString() {
        /*return "Card{" +
                "suit='" + suit + '\'' +
                ", num=" + num +
                '}';*/
        return suit +""+num;
    }
}

Cardgame:

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class Cardgame {
    public static final String[] suits = {"♥","♣","♦","♠"};

    // 买牌 (创建牌)
    public List<Card> buyCard() {
        List<Card> cardList = new ArrayList<>();
        for (int i = 0; i < 4; i++) {
            for (int j = 0; j < 13; j++) {
                cardList.add(new Card(suits[i],j));//相当于下面代码
                /*String suit = suits[i];
                Card card = new Card(suit,j)
                cardList.add(card);*/
            }
        }
        return cardList;
    }

    // 洗牌
    public void shuffle(List<Card> cardList) {
        Random random = new Random();
        for (int i = cardList.size()-1; i > 0; i--) {
            int index = random.nextInt(i);

            swap(cardList,i,index);
        }
    }

    private static void swap(List<Card> cardList,int i,int j) {
        Card tmp = cardList.get(i);
        cardList.set(i,cardList.get(j));
        cardList.set(j,tmp);
    }

    // 发牌 3个人每个人轮流抓5张牌
    // 思路:1.每个人拿到牌 放到哪
    //      2. l轮流怎么抓5张牌

    public List<List<Card>> getCard(List<Card> cardList) {
        List<Card> hand1 = new ArrayList<>();
        List<Card> hand2 = new ArrayList<>();
        List<Card> hand3 = new ArrayList<>();

        List<List<Card>> hand = new ArrayList<>();
        hand.add(hand1);
        hand.add(hand2);
        hand.add(hand3);

        for (int i = 0; i < 5; i++) {  // 拿五次牌
            for (int j = 0; j < 3; j++) {  // 3个人
                //怎么揭牌?  每次相当于 删除下0标这个牌
                Card card = cardList.remove(0);
                // 怎么放到对应人的手里面?
                hand.get(j).add(card);
            }
        }
        return hand;
    }
}

Main测试:

import java.util.List;

public class Main {
    public static void main(String[] args) {
        Cardgame cardgame = new Cardgame();
        List<Card> ret = cardgame.buyCard();
        System.out.println("买牌:");
        System.out.println(ret);

        cardgame.shuffle(ret);
        System.out.println("洗牌:");
        System.out.println(ret);

        System.out.println("揭牌:");
        List<List<Card>> hand = cardgame.getCard(ret);
        for (int i = 0; i < hand.size(); i++) {
            System.out.println("第"+(i+1)+"个人的牌"+hand.get(i));
        }
        System.out.println("剩下的牌");
        System.out.println(ret);
    }

}

在这里插入图片描述

5.2 杨辉三角的实现

具体要求:
在这里插入图片描述

    public List<List<Integer>> generate(int numRows) {
        // 定义一个二维数组
        List<List<Integer>> ret = new ArrayList<>();

        List<Integer> list = new ArrayList<>();
        list.add(1);

        ret.add(list);

        for (int i = 1; i < numRows; i++) {
            //每循环一次  就是一行
            List<Integer> curRow = new ArrayList<>();
            curRow.add(1);  //每行的第一个元素

            //处理中间的数字
            List<Integer> preRow = ret.get(i-1);
            for (int j = 1; j < i; j++) {
                int x = preRow.get(j)+preRow.get(j-1);
                curRow.add(x);
            }

            //处理最后一个数字
            curRow.add(1);

            ret.add(curRow);
        }
        return ret;
    }

6 面试题

CVTE面试题:
str1:“welcome to cvte”
str2: “come”
删除字符串1当中,出现的所有字符串2当中的字符, 即结果为 “wl t vt”

public class Test {
    public static List<Character> func(String str1,String str2) {
        List<Character> list = new ArrayList<>();
        for (int i = 0; i < str1.length(); i++) {
            char ch = str1.charAt(i);
            if(!str2.contains(ch+"")) { //contains接收的是字符串  所以字符ch +""
                list.add(ch);
            }
        }
        return list;
    }
    public static void main(String[] args) {
        List<Character> ret = func("welcome to cvte","come");
        for (Character ch:ret) {
            System.out.print(ch);
        }
    }
}

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

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

相关文章

Python 网络爬虫(二):HTTP 基础知识

《Python入门核心技术》专栏总目录・点这里 文章目录 1. HTTP 协议简述2. HTTP 请求过程3. HTTP 的结构3.1 请求行3.2 请求头3.3 请求体3.4 状态行3.5 响应头3.6 响应体4. Cookie 状态管理5. HTTP 请求示例6. 总结<

HTML5+CSS3小实例:3D翻转Tab选项卡切换特效

实例:3D翻转Tab选项卡切换特效 技术栈:HTML+CSS 效果: 源码: 【HTML】 <!DOCTYPE html> <html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"><meta name="viewport" content=…

【Linux】公网远程访问AMH服务器管理面板

目录 1. Linux 安装AMH 面板2. 本地访问AMH 面板3. Linux安装Cpolar4. 配置AMH面板公网地址5. 远程访问AMH面板6. 固定AMH面板公网地址 AMH 是一款基于 Linux 系统的服务器管理面板&#xff0c;它提供了一系列的功能&#xff0c;包括网站管理、FTP 管理、数据库管理、DNS 管理、…

信号完整性分析

目录 前言一、信号完整性SI1.1 信号失真1.2 串扰1.3 衰减 二、电源完整性PI2.1 地弹2.2 电源轨道塌陷 三、电磁兼容EMC3.1 电磁辐射3.2 抗干扰 前言 本篇介绍信号完整性分析的知识体系&#xff0c;以及部分分析方法。   什么是信号完整性?通俗来讲&#xff0c;信号在互连线的…

若依角色与权限字符串

文章目录 一、简介1.基于权限字段串2.基于角色 二、若依的权限控制1.介绍2.实践 一、简介 基于权限字段串和基于角色的访问控制是两种不同的权限管理模型&#xff0c;它们各自有其优点和应用场景。下面是这两种模型的基本概念&#xff1a; 1.基于权限字段串 基于权限字段串&…

基于ssm实验室课程管理系统源码和论文

idea 数据库mysql5.7 数据库链接工具&#xff1a;navcat,小海豚等 环境&#xff1a; jdk8 tomcat8.5 摘 要 随着科学实验规模的不断扩大&#xff0c;实验室课程数量的急剧增加&#xff0c;有关实验室课程的各种信息量也在不断成倍增长。面对庞大的信息量&#xff0c;就需要有…

SpringCloud简介和用处

Spring Cloud是一套基于Spring Boot的微服务框架&#xff0c;它旨在提供一种快速构建分布式系统的方法。它可以帮助开发人员构建具有高可用性、可扩展性和容错性的微服务&#xff0c;并通过Spring Boot的开发工具和库提供强大的支持。 一、简介 Spring Cloud是Spring家族中的一…

Spark Structured Streaming使用教程

文章目录 1、输入数据源2、输出模式3、sink输出结果4、时间窗口4.1、时间窗口4.2、时间水印&#xff08;Watermarking&#xff09; 5、使用例子 Structured Streaming是一个基于Spark SQL引擎的可扩展和容错流处理引擎&#xff0c;Spark SQL引擎将负责增量和连续地运行它&#…

2023-2024-1-高级语言程序设计-第2次月考编程题

注&#xff1a;此前已发布过的题解不再发布&#xff08;原题请在下面位置进行搜索&#xff09;。 7-1-2 排序(算法任意) 本题要求将给定的n个整数从大到小排序后输出&#xff08;可使用任意排序算法&#xff09;。 输入格式: 输入第一行给出一个不超过10的正整数n。第二行给…

WVP-RPO开源项目搭建实践

0.拉取代码 GitHub - 648540858/wvp-GB28181-pro: WEB VIDEO PLATFORM是一个基于GB28181-2016标准实现的网络视频平台&#xff0c;支持NAT穿透&#xff0c;支持海康、大华、宇视等品牌的IPC、NVR、DVR接入。支持国标级联&#xff0c;支持rtsp/rtmp等视频流转发到国标平台&…

详细解读电力DLT698.45-2017通信规约--正向有功总电能

建立连接请看这篇&#xff1a;详细解读DLT698.45-2017通信规约--预连接响应http://mp.weixin.qq.com/s?__bizMzA3NjAwMjQzMQ&mid2652026396&idx1&sna0a17f005d23136c922a7c381ddb7e75&chksm8481f30cb3f67a1a94e66db77e61fe73c22b1904fcdbb0144108e132b265e7b4…

dtaidistance笔记:dtw_ndim (高维时间序列之间的DTW)

1 数据 第一个维度是sequence的index&#xff0c;每一行是多个元素&#xff08;表示这一时刻的record&#xff09; from dtaidistance.dtw_ndim import *s1 np.array([[0, 0],[0, 1],[2, 1],[0, 1],[0, 0]], dtypenp.double) s2 np.array([[0, 0],[2, 1],[0, 1],[0, .5],[0…

水果党flstudio用什么midi键盘?哪个版本的FL Studio更适合我

好消息&#xff01;好消息&#xff01;特大好消息&#xff01; 水果党们&#xff01;终于有属于自己的专用MIDI键盘啦&#xff01; 万众期待的Novation FLKEY系列 正式出炉&#xff01; 话有点多话&#xff0c;先分享一份干货&#xff0c;尽快下载 FL Studio 21 Win-安装包&…

搜索推荐技术-爱奇艺搜索引擎技术

一、爱奇艺的搜索引擎框架示意图 即通过召回系统&#xff0c;即基于文本匹配的matching system&#xff0c;得到大量视频资源的候选集&#xff0c;经过粗排和精排&#xff0c;最后返回给用户。重点在于召回模块和排序模块。 二、召回模块 召回模块比较重要的是基础相关性&am…

Unity Meta Quest 一体机开发(九):【手势追踪】通过录制抓取手势实现自定义抓取姿势

文章目录 &#x1f4d5;教程说明&#x1f4d5;录制前的准备&#x1f4d5;第一种录制方法&#xff08;Hand Grab Pose Tool 场景&#xff09;⭐在运行模式中确认录制⭐保存录制的手势&#xff0c;将物体做成 Prefab⭐在编辑阶段调整抓取手势&#x1f50d;Fingers Freedom&#x…

leetcode 622. 设计循环链表

这道题讲了两种方法&#xff0c;第一个代码是用数组实现的&#xff0c;第二个是用链表实现的&#xff0c;希望对你们有帮助 &#xff08;最好在VS自己测试一遍&#xff0c;再放到 leetcode上哦&#xff09; 下面的是主函数&#xff08;作参考&#xff09;&#xff0c;静下心来…

第21章网络通信

Internet 提供了大量有用的信息&#xff0c;很少有人能在接触过Internet后拒绝它的诱惑。计算机网络实现了多台计算机间的互联&#xff0c;使得它们彼此之间能够进行数据交流。网络应用程序就是在已连接的不同计算机上运行的程序&#xff0c;这些程序借助于网络协议&#xff0c…

孩子都能学会的FPGA:第二十四课——用FPGA和格雷码实现异步FIFO

&#xff08;原创声明&#xff1a;该文是作者的原创&#xff0c;面向对象是FPGA入门者&#xff0c;后续会有进阶的高级教程。宗旨是让每个想做FPGA的人轻松入门&#xff0c;作者不光让大家知其然&#xff0c;还要让大家知其所以然&#xff01;每个工程作者都搭建了全自动化的仿…

加载离线镜像包:在线镜像离线为tar包、tar离线镜像包加载并根据imageId打tag

第一步&#xff1a;在线环境压缩离线镜像&#xff1a; 需要两个文件&#xff0c;第一个是脚本文件image_offline_load.sh脚本&#xff0c;第二个是image_list.txt 按行 存放需要离线的镜像名称 ./image_offline_load.sh save image_list.txt output.tar第二步&#xff1a;在离…

Nginx 简单入门操作

前言:之前的文章有些过就不罗嗦了。 Nginx 基础内容 是什么? Nginx 是一个轻量级的 HTTP 服务器,采用事件驱动、异步非阻塞处理方式的服务器,它具有极好的 IO 性能,常用于 HTTP服务器(包含动静分离)、正向代理、反向代理、负载均衡 等等. Nginx 和 Node.js 在很多方…