Java实现数据结构——顺序表

目录

一、前言

二、实现

2.1 增

2.2 删

2.3 查 

 2.4 改

 2.5 销毁顺序表

三、Arraylist

3.1 构造方法

 3.2 常用操作

3.3 ArrayList遍历

四、 ArrayList具体使用  

4.1 杨辉三角

4.2 简单洗牌算法


一、前言

笔者在以前的文章中实现过顺序表

本文在理论上不会有太详细的讲述

如有需要可以翻看笔者之前的文章

http://t.csdnimg.cn/G5TpF


Java 中已经封装好了顺序表的类

但在使用之前

先自己实现一遍 

二、实现

将顺序表作为一个类进行实现

public class MyArrayList {private int[] array ;//以整形数组示例private static int defaultspace = 10;//默认数组大小private int usespace = 0;//顺序表有效数据个数// 构造方法public MyArrayList() {this.array = new int[defaultspace];//不指定大小就默认大小}public MyArrayList(int size) {this.array = new int[size] ;//用户自己指定大小}
}

再给一个方法让用户可以知晓表中有效数据个数

  public int size(){return this.usespace;}

2.1 增

这里进行一个方法的重载

   public void add(int data){
//     不指定位置就默认是数组尾插入数据}public void add(int data ,int pos){
//指定位置就插入到指定位置

在进行数据插入时

需要判断顺序表中是否还有足够的空间

给一个方法

检查操作不需要用户来使用

那就用 private 来修饰

   private boolean IsFull() {
//        检查顺序表空间是否还有剩余return usespace == this.array.length;}

如果顺序表空间没有剩余

就需要扩容这个顺序表

这里选择使用 Arrays 类中的 copyOf 方法

    public void add(int data) {
//     不指定位置就默认是数组尾插入数据if (IsFull(array)) {this.array = Arrays.copyOf(array, array.length * 2);}array[usespace] =  data;usespace++;

 将上述操作封装进一个方法 checkspace

 private void checkspace() {if (IsFull()) {array = Arrays.copyOf(array, array.length * 2);}}
   public void add(int data) {
//     不指定位置就默认是数组尾插入数据checkspace();this.array[usespace++] = data;}


而在指定位置的 add 方法中

 则是需要检查插入位置是否合法

这个下标的合法区间是 0~顺序表有效数据个数

那么不止在增删查改中都会有操作涉及到检查要进行操作的位置是否合法

不妨将操作位置不合法作为异常处理

自定义一个异常类

public class Pos_IllegalityException extends RuntimeException{public Pos_IllegalityException(String message) {super(message);}
}

检查操作不需要用户来使用

那就用 private 来修饰

  private void checkPos(int pos) throws Pos_IllegalityException {//检查插入位置是否合法if(pos < 0 || pos > usespace){throw new Pos_IllegalityException("输入的下标不合法:"+pos);}}

指定位置插入数据后

需要将原 pos及其以后得数据向后移动

    public void add(int data, int pos) {
//指定位置就插入到指定位置try {checkPos_add(pos);} catch (Pos_IllegalityException e) {e.printStackTrace();}checkspace();for (int i = usespace; i >= pos; i--) {this.array[i + 1] = this.array[i];}this.array[pos] = data;this.usespace++;}

在实现一个打印方法

便于测试

  public void print() {for (int i = 0; i < usespace; i++) {System.out.println(array[i]);}}

测试

  public static void main(String[] args) {MyArrayList arr1 = new MyArrayList();arr1.add(1);arr1.add(2,0);arr1.add(3,1);arr1.add(4);arr1.add(5);arr1.print();}
}


测试是否能捕捉到异常

 public static void main(String[] args) {MyArrayList arr1 = new MyArrayList();arr1.add(1);arr1.add(2,0);arr1.add(3,10);arr1.add(4);arr1.add(5);arr1.print();}

 

 符合预期

2.2 删

在进行删除操作的时候

这个顺序表肯定不能为空

就要先判断

   private boolean IsEmpty() {return this.usespace == 0;}
public void remove(int pos){}

在进行指定位置删除时,同样需要判断进行操作的位置是否合法

删除操作中

pos 合法范围是[0,usespace)

  private void chechPos_remove(int pos) throws Pos_IllegalityException {//检查删除位置是否合法if (pos < 0 || pos >= this.usespace) {throw new Pos_IllegalityException("输入的下标不合法:" + pos);}}

删除 pos 位置的数据就是将 pos 位置后的数据向前移动一位

pos + 1 位置开始向前覆盖

public void remove(int pos) {//删除指定位置的数据if (IsEmpty()) {System.out.println("当前没有可以删除的数据");}try {chechPos_remove(pos);} catch (Pos_IllegalityException e) {e.printStackTrace();}for (int i = pos; i < this.usespace - 1; i++) {this.array[i] = this.array[i + 1];}this.usespace--;}

测试

public static void main(String[] args) {MyArrayList arr1 = new MyArrayList();arr1.add(1);arr1.add(2);arr1.add(3);arr1.add(4);arr1.add(5);arr1.print();System.out.println("===========================");arr1.remove(0);arr1.remove(arr1.size() - 1);arr1.print();}


测试是否能捕捉异常

public static void main(String[] args) {MyArrayList arr1 = new MyArrayList();arr1.add(1);arr1.add(2);arr1.add(3);arr1.add(4);arr1.add(5);arr1.print();System.out.println("===========================");arr1.remove(0);arr1.remove(arr1.size() );arr1.print();}

符合预期

2.3 查 

用两个方法

一个叫 indexOf 

  public int indexOf(int data)

找到对应数据返回对应下标

找不到返回 -1

一个叫 get

public int get(int pos)

查找对应下标的数据


先说 indexOf

同样的

在查找时

也需要判断顺序表中是否有数据

public int indexOf(int data) {if (IsEmpty()) {}return -1;}

为空或者表中没这个数据都返回-1

找到了就返回对应的下标

   public int indexOf(int data) {
//        查找数据对应的下标if (IsEmpty()) {return -1;}for (int i = 0; i < this.usespace; i++) {if (this.array[i] == data) {return i;}}return -1;}


现在说 get

public int get(int pos)throws {
//        查找对应下标的数据if (IsEmpty()) {}}

那么在这里遇到了一个小问题

在这个顺序表为空的情况下

返回值该是什么呢

似乎任意一个整数都不太适合进行返回

那么干脆将顺序表为空作为一种异常处理

public class MyArrayListEmptyException extends RuntimeException{public MyArrayListEmptyException(String message) {super(message);}
}

再将前文中删操作时也应用这个异常

 public void remove(int pos) throws MyArrayListEmptyException {//删除指定位置的数据if (IsEmpty()) {throw new MyArrayListEmptyException("当前顺序表为空!");}try {chechPos_remove(pos);} catch (Pos_IllegalityException e) {e.printStackTrace();}for (int i = pos; i < this.usespace - 1; i++) {this.array[i] = this.array[i + 1];}this.usespace--;}

然后完成 get 的逻辑

同样的

需要检查传入下标的合法性

这里传入下标的合法性与删除操作的合法范围相同

那么就可以调用 chechPos_remove 这个方法

为了方便就改个名

 private void chechPos_remove_and_get(int pos) throws Pos_IllegalityException {//检查删除位置是否合法if (pos < 0 || pos >= this.usespace) {throw new Pos_IllegalityException("输入的下标不合法:" + pos);}}
   public int get(int pos) throws MyArrayListEmptyException {
//        查找对应下标的数据chechPos_remove_and_get(pos);if (IsEmpty()) {throw new MyArrayListEmptyException("当前顺序表为空");}return this.array[pos];}

测试

 public static void main(String[] args) {MyArrayList arr1 = new MyArrayList();arr1.add(99);arr1.add(2);arr1.add(3);System.out.println(arr1.indexOf(3));System.out.println(arr1.indexOf(4));System.out.println(arr1.get(0));}

这里看起来好像没问题

需要注意的是

如果是顺序表中所存数据是引用数据类型

那么

就不能使用 == 号判断

需要重写 equals 方法

 2.4 改

通过一个 set 方法来实现

public void set(int data ,int pos){}

类似的

顺序表不能为空

判断 pos 是否合法

合法区间也是[0,usespace)

那再改个名

private void checkPos_remove_get_set(int pos) throws Pos_IllegalityException {//检查删除位置是否合法if (pos < 0 || pos >= this.usespace) {throw new Pos_IllegalityException("输入的下标不合法:" + pos);}}

完成 set 的实现

public void set(int data, int pos) throws MyArrayListEmptyException{//修改表中数据if(IsEmpty()){throw new MyArrayListEmptyException("当前顺序表为空");}checkPos_remove_get_set(pos);this.array[pos] = data;}

测试

 public static void main(String[] args) {MyArrayList arr1 = new MyArrayList();arr1.add(99);arr1.add(2);arr1.add(3);arr1.set(199,0);arr1.set(299,1);arr1.print();}

 2.5 销毁顺序表

顺序表在使用完成之后需要进行销毁

如果顺序表存的是基本数据类型

可以直接让 usespace = 0

 public void clear(){this.usespace = 0;}

但是如果是引用数据类型

采用这种方法会造成内存泄漏

JVM 中的自动回收算法有一个要求便是没引用这个数据

而这里虽然将 usespacez 置为0了

但数组中的对象仍然是存储在内存当中的

0下标确实还在引用这个对象

那么最粗暴的方法

就是直接将数组置空

  public void clear(){this.array = null;}

平和一点就是写一个循环

让每一项都置空

public void clear(){for (int i = 0; i <this. usespace; i++) {this.array[i] = null;}}

那为什么基本数据类型不需要回收呢

比如这里的 int

就算不主动向表中插入数据

表中对应下标位置仍会有默认的 0

到这里

自己实现的一个简单顺序表就完成了

下面来看看 Java 中实现的 Arraylist

三、Arraylist

接下来来看一下 Java 中已经封装好的 Arraylist

这里只展示部分方法


3.1 构造方法

 来看看提供的构造方法


其中这个构造方法是由使用者指定顺序表大小

指定空间大小不合法就抛出一个异常


现在来看看这个无参构造方法 

可以看到的是

如果调用无参构造方法

并没有给数组分配内存空间

public static void main(String[] args) {ArrayList arrayList = new ArrayList<>();arrayList.add(1);arrayList.add(2);arrayList.add(3);for (int i = 0; i < arrayList.size(); i++) {System.out.println(arrayList.get(i));}}

 

但是可以看到的是

往这个表中插入数据

还是可以成功插入

这时候就去看看方法 add 中是怎么执行的

 就是通过上述步骤

elementData 指定了一片内存空间

能够完成 add 操作


 

public static void main(String[] args) {ArrayList<Integer> arrayList1 = new ArrayList<>();ArrayList<Number> arrayList2 = new ArrayList<>(arrayList1);}

 

 public static void main(String[] args) {ArrayList<Integer> arrayList1 = new ArrayList<>();ArrayList<Number> arrayList2 = new ArrayList<>(arrayList1);LinkedList<Number> linkedList = new LinkedList<>(arrayList1);Vector<Number> vector = new Vector<>(arrayList1);}

 

都是可以的

而不满足上述条件

  public static void main(String[] args) {ArrayList<String> arrayList1 = new ArrayList<>();ArrayList<Number> arrayList2 = new ArrayList<>(arrayList1);}

 

 3.2 常用操作

方法作用
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 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<E> subList (int fromIndex, int toIndex)
截取部分list
…………

这里主要说说重载的 remove 方法

    public static void main(String[] args) {ArrayList<Integer> arrayList = new ArrayList<>();arrayList.add(1);arrayList.add(2);arrayList.add(3);arrayList.add(4);arrayList.add(5);for (int i = 0; i < arrayList.size(); i++) {System.out.print(arrayList.get(i)+" ");}arrayList.remove(3);System.out.println();for (int i = 0; i < arrayList.size(); i++) {System.out.print(arrayList.get(i)+" ");}}

如果只传一个整形数字

删除的是对应下标的值 

如果想要具体删除某一个数据

那就要 new 一个对象

  public static void main(String[] args) {ArrayList<Integer> arrayList = new ArrayList<>();arrayList.add(1);arrayList.add(2);arrayList.add(3);arrayList.add(4);arrayList.add(5);for (int i = 0; i < arrayList.size(); i++) {System.out.print(arrayList.get(i)+" ");}arrayList.remove(new Integer(3));System.out.println();for (int i = 0; i < arrayList.size(); i++) {System.out.print(arrayList.get(i)+" ");}}


以及 subList 方法

public static void main(String[] args) {ArrayList<Integer> arrayList = new ArrayList<>();arrayList.add(1);arrayList.add(2);arrayList.add(3);arrayList.add(4);arrayList.add(5);List<Integer> list = arrayList.subList(0,3);for (int i = 0; i < list.size(); i++) {System.out.print(list.get(i)+" ");}arrayList.set(0,99);System.out.println();for (int i = 0; i < list.size(); i++) {System.out.print(list.get(i)+" ");}}

截取后并不是产生新的对象

而是将截取的地址返回

所以在修改 arraylist 的值后

list 也会被修改

3.3 ArrayList遍历

ArrayList 可以使用三方方式遍历: for循环+ 下标 foreach 使用迭代器
for循环+ 下标在前文已经使用,这里就不再赘述
public  static void main(String[] args) {ArrayList<Integer> arrayList = new ArrayList<>();arrayList.add(1);arrayList.add(2);arrayList.add(3);arrayList.add(4);arrayList.add(5);for (Integer integer:arrayList){System.out.println(integer);}}


迭代器

使用方法

  public  static void main(String[] args) {ArrayList<Integer> arrayList = new ArrayList<>();arrayList.add(1);arrayList.add(2);arrayList.add(3);arrayList.add(4);arrayList.add(5);Iterator<Integer> integerIterator = arrayList.iterator();while (integerIterator.hasNext()){System.out.println(integerIterator.next());}}

 

四、 ArrayList具体使用  

4.1 杨辉三角

题目来源

https://leetcode.cn/problems/pascals-triangle/description/


 这段代码表示

指定 对象 list 中存放的类型是 List<Integer>

 public static void main(String[] args) {List<List<Integer>> list = new ArrayList<>();ArrayList<Integer> arrayList = new ArrayList<>();ArrayList<Integer> arrayList2 = new ArrayList<>();list.add(arrayList);list.add(arrayList2);System.out.println();}

打个断点观察一下

可以看到其中存放的确实是 ArrayList 类型的对象


在本题中可以将整个杨辉三角看成是一个 List< List<Integer>> 对象

每一行就是单独的一个 Arraylist 对象 

就可以将 numRows Arraylist 对象增加到 List< List<Integer>> 对象中

完成这个杨辉三角


每一个 Arraylist 对象首元素和尾元素都是 1

就只需要给 (0,Arraylist 对象.length()) 下标处进行计算赋值

  public List<List<Integer>> generate(int numRows) {List<List<Integer>> list = new ArrayList<>();//        第一行只有一个元素 1List<Integer> firstrow = new ArrayList<>();firstrow.add(1);list.add(firstrow);//插入listfor (int i = 1; i < numRows; i++) {List<Integer> currow = new ArrayList<>();//当前行currow.add(1);//当前行的首元素for (int j = 1; j < i; j++) {
//                只进行(0,尾元素下标)之间的值赋值}currow.add(1);//尾元素赋值list.add(currow);//插入list}return list;}

而处于这个范围内的值等于

上一行同一列的值+上一行前一列的值

而对于当前代码来说

以第三行为例

list 中的第二个存储的对象

通过 get 方法将获取

public List<List<Integer>> generate(int numRows) {List<List<Integer>> list = new ArrayList<>();//        第一行只有一个元素 1List<Integer> firstrow = new ArrayList<>();firstrow.add(1);list.add(firstrow);//插入listfor (int i = 1; i < numRows; i++) {List<Integer> currow = new ArrayList<>();//当前行currow.add(1);//当前行的首元素for (int j = 1; j < i; j++) {
//                只进行(0,尾元素下标)之间的值赋值List<Integer> lastrow = list.get(i - 1);//上一行int num = lastrow.get(j) + lastrow.get(j - 1);currow.add(num);}currow.add(1);//尾元素赋值list.add(currow);//插入list}return list;}

现在来提交一下

可以看到是可行的

4.2 简单洗牌算法

假设有三人正在玩扑克牌

设计一个洗牌算法

这里不计入大小王

总共有五十二张牌

花色有四种

♠(黑桃)、♥(红桃)、♦(方块)、♣(梅花)

每种花色各有13张

J Q K A 用数字 11,12,13,1代替

大概逻辑如下


可以把每一张牌看成是一个对象

那就需要一个牌类

public class Card {private String color;//花色 ♠(黑桃)、♥(红桃)、♦(方块)、♣(梅花)private int point;//点数 1,2,3,4,5,6,7,8,9,10,11,12,13public  Card(){}public Card(String color, int point) {this.color = color;this.point = point;}public void setColor(String color) {this.color = color;}public void setPoint(int point) {this.point = point;}@Overridepublic String toString() {return "[" +color + '\''+ point +"]";}
}

那么 Card 类实例化出来的 52 个对象放到一个牌组 CardList

public class CardList {
//牌组public static List<Card> BuyCard(){List<Card> cardList = new ArrayList<>();return cardList;}
}

再创建一个 Colors 类表示花色

Points 类表示点数

public class Colors {//花色private static String[] colors = {"♠","♥","♦","♣"};public static String getColors(int index) {return colors[index];}public static int size(){return colors.length;}}
public class Points {//点数private static int[] points = {1,2,3,4,5,6,7,8,9,10,11,12,13};public static int getPoints(int index) {return points[index];}public static int size(){return points.length;}
}

通过这个类的静态方法返回一个 List<Card> 类对象

public static List<Card> BuyCard(){List<Card> cardList = new ArrayList<>();for (int i = 0; i < Colors.size(); i++) {for (int j = 0; j < Points.size(); j++) {Card card = new Card(Colors.getColors(i),Points.getPoints(j));cardList.add(card);}}return cardList;}

在通过循环给每张牌进行 colorpoint 的赋值

public static List<Card> BuyCard(){List<Card> cardList = new ArrayList<>();for (int i = 0; i < Colors.size(); i++) {for (int j = 0; j < Points.size(); j++) {Card card = new Card(Colors.getColors(i),Points.getPoints(j));cardList.add(card);}}return cardList;}

再将牌放入数组中

打印出来看看

public static void main(String[] args) {List<Card> cardList = CardList.BuyCard();System.out.println(cardList);}

 (仅展示部分)

那么生成一副牌的逻辑就完成了


现在要洗乱这副牌

其实就是交换 cardlist 中存放的牌的位置

即两个下标的数据互换

而要随机洗乱就要生成随机数

可以使用 Random

Random random = new Random();random.nextInt();

random.nextInt() 传入一个整形 n 可以限制只生成 0~n 之间的整数

那么可以遍历 cardlist 

将遍历过程中的下标作为限制传入

这里选择从尾部开始遍历

private static void shuffle(List<Card> cardList) {Random random = new Random();for (int i = cardList.size() - 1; i > 0; i--) {int index = random.nextInt(i);}}

然后需要有一个交换的操作

可以通过 List 中的 set 方法

将交换的操作封装成一个方法

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

放到生成牌的方法中 

   public static List<Card> BuyCard() {List<Card> cardList = new ArrayList<>();for (int i = 0; i < Colors.size(); i++) {for (int j = 0; j < Points.size(); j++) {Card card = new Card(Colors.getColors(i), Points.getPoints(j));cardList.add(card);}}shuffle(cardList);return cardList;}

测试一下看下行不行

public static void main(String[] args) {List<Card> cardList = CardList.BuyCard();System.out.println(cardList);}

(仅展示部分)

可以看到顺序确实是被洗乱了


发给三个人,每人一开始有五张

可以把玩家看成是一个专门存放 List<Card> 类对象的 List

cardlist 中摸牌就是 add

    public static void main(String[] args) {List<Card> cardList = CardList.BuyCard();List<List<Card>> player= new ArrayList<>();//人for (int i = 0; i < 3 ; i++) {//i表示人List<Card> list = new ArrayList<>();for (int j = i * 5; j < i * 5 + 5; j++) {list.add(cardList.get(j));}player.add(list);System.out.println(player.get(i));}}

感谢观看

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

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

相关文章

vscode侧边栏错乱重制

vscode 重制命令面板 View: Reset View Locations

三星系统因何而成?或许是因为吞噬了第四颗恒星

相比于其他的类似星体&#xff0c;这个特殊的三星系统拥有更大更紧密的星体。 三星 天文学家发现了前所未见的三星系统。相比于其他典型的三星系统&#xff0c;这一三星系统拥有更大的体积&#xff0c;并且排列也更加紧密&#xff0c;这也使得这一系统更加特别。科学家推测&am…

【题解】—— LeetCode一周小结23

&#x1f31f;欢迎来到 我的博客 —— 探索技术的无限可能&#xff01; &#x1f31f;博客的简介&#xff08;文章目录&#xff09; 【题解】—— 每日一道题目栏 上接&#xff1a;【题解】—— LeetCode一周小结22 3.分糖果 II 题目链接&#xff1a;1103. 分糖果 II 排排坐…

MySQL-数据处理(1)

029-数据处理函数之获取字符串长度 select length(我是Cupid); select char_length(我是Cupid);concat (concatenate) select concat(cu, pid, so, handsome);030-去除字符串前后空白-trim select trim( a b c );select trim(leading 0 from 000110); select t…

USB转I2C转SPI芯片CH341

CH340与CH341区别 CH340主要用于将USB转换为各种串口&#xff0c;CH340H和CH340S可以实现USB转并口。 CH341和340的不同之处在于CH341提供I2C和SPI接口&#xff0c;方便连接到I2C或SPI总线操作相关的器件。 CH341主要有6种封装。见表1. CH341T SSOP-20封装和丝印 USB 总线转接…

【服务实现读写分离】

文章目录 什么是读写分离基于Spring实现实现读写分离项目中常用的数据源切换依赖包 什么是读写分离 服务读写分离&#xff08;Service Read-Write Splitting&#xff09;是一种常见的数据库架构设计模式&#xff0c;旨在提高系统的性能和可扩展性。通过将读操作和写操作分离到…

分布式事务AP控制方案(上)

分布式事务控制方案 本篇文章给出一种要求高可用性&#xff08;AP思想&#xff09;的分布式事务控制方案 下篇新鲜出炉&#xff1a;点我查看 分布式事务控制方案1、业务背景2、本地消息表的设计3、对消息表的操作4、任务调度5、任务流程控制的抽象类6、课程发布的实现类7、总…

优质免费的 5 款翻译 API 接口推荐

当谈到翻译API时&#xff0c;我们通常指的是一种编程接口&#xff0c;它允许开发者将文本从一种语言翻译成另一种语言。这些API通常由专业的翻译服务提供商提供&#xff0c;如谷歌翻译 API、实时翻译API、腾讯翻译API、DeepL翻译API、Azure翻译API等。 这些API通常提供多种语言…

使用Redis的优势以及会引发的问题

优势 ①使用redis代表着高性能还有高并发&#xff0c;高性能很好理解&#xff0c;redis会缓存我们访问的数据。他是基于内存的&#xff0c;第一次访问数据库我们可能需要800ms&#xff0c;但是访问后如果使用redis进行缓存&#xff0c;第二次乃至后面访问相同的数据就只需要去…

使用opencv在图像上画带刻度线的对角线,以图像中心点为0点

使用OpenCV在图像上绘制带刻度线的对角线&#xff0c;可以通过以下步骤实现。我们将首先找到图像的中心点&#xff0c;然后绘制对角线线&#xff0c;并在这些线的适当位置绘制刻度线。以下是详细的C代码示例&#xff1a; void Draw_diagonal(cv::Mat& mat, double dFactor…

ViT:2 理解CLIP

大模型技术论文不断&#xff0c;每个月总会新增上千篇。本专栏精选论文重点解读&#xff0c;主题还是围绕着行业实践和工程量产。若在某个环节出现卡点&#xff0c;可以回到大模型必备腔调或者LLM背后的基础模型新阅读。而最新科技&#xff08;Mamba,xLSTM,KAN&#xff09;则提…

《永生之后》读后

文章以2120年背景创作&#xff0c;人类进入永生之年&#xff0c;发现了延长寿命的药物。停滞的死亡&#xff0c;新生的继续造生了人口大爆炸&#xff0c;于是分成两个阵营-长生区&#xff08;不再繁衍后代&#xff09;与生死区&#xff08;不服用药物&#xff0c;仍然生老病死&…

PySpark教程(001):基础准备与数据输入

PySpark 学习目标 了解什么是Spark、PySpark了解为什么学习PySpark了解如何和大数据开发方向进行衔接 Spark是什么&#xff1f; Apache Spark是用于大规模数据处理的统一分析引擎。 简单来说&#xff0c;Spark是一款分布式的计算框架&#xff0c;用于调度成百上千的服务器…

MyBatis总结(2)- MyBatis实现原理(一)

Mybatis实现原理&#xff1a; 概括一句话&#xff1a;约定配置参数mybatis-config.xml&#xff0c;映射关系JavaBean-mapper.xml&#xff0c;用SqlSessionFactoryBuilder构建应用程序运行期间需要的SqlSessionFactory实例对象&#xff0c;当请求或方法需要执行CURD操作时&…

初识volatile

volatile&#xff1a;可见性、不能保证原子性(数据不安全)、禁止指令重排 可见性&#xff1a;多线程修改共享内存的变量的时候&#xff0c;修改后会通知其他线程修改后的值&#xff0c;此时其他线程可以读取到修改后变量的值。 指令重排&#xff1a;源代码的代码顺序与编译后字…

基于STM32开发的智能空气质量监控系统

⬇帮大家整理了单片机的资料 包括stm32的项目合集【源码开发文档】 点击下方蓝字即可领取&#xff0c;感谢支持&#xff01;⬇ 点击领取更多嵌入式详细资料 问题讨论&#xff0c;stm32的资料领取可以私信&#xff01; 目录 引言环境准备智能空气质量监控系统基础代码实现&…

三十七篇:大数据架构革命:Lambda与Kappa的深度剖析

大数据架构革命:Lambda与Kappa的深度剖析 1. 引言 在这个数据驱动的时代,我们面临着前所未有的挑战和机遇。随着数据量的爆炸性增长,传统的数据处理方法已无法满足现代业务的需求。大数据处理不仅涉及数据量的增加,还包括数据类型的多样化、数据来源的广泛性以及对实时数据…

Policy-Based Reinforcement Learning(1)

之前提到过Discount Return&#xff1a; Action-value Function &#xff1a; State-value Function: &#xff08;这里将action A积分掉&#xff09;这里如果策略函数很好&#xff0c;就会很大&#xff1b;反之策略函数不好&#xff0c;就会很小。 对于离散类型&#xff1a; …

深度学习之文本分类模型-基于transformer

1、transformer transformer就是大名鼎鼎的论文《Attention Is All You Need》[1]&#xff0c;其在一些翻译任务上获得了SOTA的效果。其模型整体结构如下图所示 encoder和decoder 其整体结构由encoder和decoder组成&#xff0c;其中encoder由6个相同的block组成&#xff0c;…

【设计模式】结构型-桥接模式

当抽象与实现&#xff0c;各自独立&#xff0c; 桥接模式&#xff0c;如彩虹桥&#xff0c;连接两岸。 文章目录 一、类爆炸与代码重复二、桥接模式三、桥接模式的核心组成四、运用桥接模式五、桥接模式的应用场景六、小结推荐阅读 一、类爆炸与代码重复 场景假设&#xff1a…