当前位置: 首页 > wzjs >正文

网站建设的价值体现在哪搞个app软件需要多少钱

网站建设的价值体现在哪,搞个app软件需要多少钱,一建,北京软件股份有限公司本文内容为使用数组实现能够动态扩容且高效索引每个元素的通用类型的列表。 1. 数组构建列表 之前我们实现的列表想要索引一个中间元素都是需要遍历列表才能找到的,查找效率低下,而数组的一大特性就是无论规模有多大,想要索引某个元素的时间…

本文内容为使用数组实现能够动态扩容且高效索引每个元素的通用类型的列表。

1. 数组构建列表

之前我们实现的列表想要索引一个中间元素都是需要遍历列表才能找到的,查找效率低下,而数组的一大特性就是无论规模有多大,想要索引某个元素的时间复杂度都是 O ( 1 ) O(1) O(1)

我们可以用数组来设计之前写过的列表,我们先设定数组的最大长度为100,当数组还未填满时可以称未使用的那部分为后备数组:

package CS61B.Lecture7;public class AList {private int[] items;private int size;private final int MAX_SIZE = 100;public AList() {this.items = new int[this.MAX_SIZE];this.size = 0;}public int get(int idx) {return this.items[idx];}public int size() {return this.size;}public void addLast(int x) {if (this.size == this.MAX_SIZE) return;this.items[this.size++] = x;}public int getLast() {if (this.size == 0) return 0;return this.items[this.size - 1];}public void removeLast() {if (this.size == 0) return;this.size--;}public static void main(String[] args) {AList L = new AList();for (int i = 0; i < 5; i++) L.addLast(i);System.out.println(L.getLast());  // 4L.removeLast();for (int i = 0; i < L.size(); i++)System.out.print(L.get(i) + " ");  // 0 1 2 3}
}

2. 改变AList的大小

如果用户的需求是需要一个能无限插入的列表,但数组在 Java 中的长度是固定的,当空间用满后如何调整数组的大小呢?此时只能创建一个新的更长的数组,然后将已满数组的内容全部复制到新数组中。

那么此时又有一个新的问题,每次需要新创建数组时这个新数组的长度设为多少合适呢?这个扩容的比例我们一般称作扩容因子,在动态数组(如 Java 的 ArrayList 或 Python 的 list)中,设置扩容因子是为了权衡时间复杂度和空间复杂度,其合理性可以通过均摊分析(Amortized Analysis)和内存管理优化来解释。

动态数组的扩容需要将旧数据复制到新内存空间,这是一个时间复杂度为 O ( n ) O(n) O(n) 的操作。若扩容策略不当,频繁扩容会导致性能下降。例如:

  • 如果每次扩容固定大小(例如加一),插入 n n n 个元素的总时间复杂度为 O ( n 2 ) O(n^2) O(n2),无法接受。
  • 如果每次扩容指数倍(例如两倍),插入 n n n 个元素的总时间复杂度可优化为 O ( n ) O(n) O(n),均摊到每次操作为 O ( 1 ) O(1) O(1)

数学推导如下(以两倍扩容为例):

假设初始容量为1,插入 n n n 个元素需要扩容 k k k 次(满足 2 k ≥ n 2^k\ge n 2kn)。总复制操作次数为:

1 + 2 + 4 + ⋯ + 2 k − 1 = 2 k − 1 ≈ 2 n 1+2+4+\dots +2^{k-1}=2^k-1\approx 2n 1+2+4++2k1=2k12n

因此,总时间复杂度为 O ( n ) O(n) O(n),均摊到每次插入操作为 O ( 1 ) O(1) O(1)

Java 与 Python 的动态数组扩容策略如下:

  • Java:ArrayList 默认扩容为1.5倍,扩容公式为 newCapacity = oldCapacity + (oldCapacity >> 1),减少内存浪费。
  • Python:list 采用过度分配(over-allocation),扩容公式为 new_size = (new_len >> 3) + (new_len < 9 ? 3 : 6),近似1.125倍。

现在我们可以实现具有动态扩容功能的列表:

package CS61B.Lecture7;public class AList {private int[] items;private int size;private int MAX_SIZE = 2;public AList() {this.items = new int[this.MAX_SIZE];this.size = 0;}public int get(int idx) {return this.items[idx];}public int size() {return this.size;}// 将数组长度扩充为capacityprivate void resize(int capacity) {int[] newItems = new int[capacity];System.arraycopy(this.items, 0, newItems, 0, this.size);this.items = newItems;}public void addLast(int x) {if (this.size == this.MAX_SIZE) {this.MAX_SIZE *= 2;this.resize(this.MAX_SIZE);}this.items[this.size++] = x;}public int getLast() {if (this.size == 0) return 0;return this.items[this.size - 1];}public void removeLast() {if (this.size == 0) return;this.size--;}public static void main(String[] args) {AList L = new AList();for (int i = 0; i < 5; i++) L.addLast(i);System.out.println(L.getLast());  // 4L.removeLast();for (int i = 0; i < L.size(); i++)System.out.print(L.get(i) + " ");  // 0 1 2 3}
}

此时会发现当列表扩容后如果用户将元素又删除了导致列表有很多空余的位置,因此还要能够实现多余空间的回收,一般会用使用率来表示列表的空间占用情况: R = s i z e / i t e m . l e n g t h R=size/item.length R=size/item.length,一个典型的解决方案就是当 R < 0.25 R<0.25 R<0.25 时将列表的大小减半。具体细节会在以后的内容中实现。

3. 通用类型ArrayList

现在我们尝试和上一节课一样使用泛型将 AList 改为通用类型的,但是当我们使用以下代码创建数组时出现了问题:

this.items = new T[this.MAX_SIZE];

这涉及到类型擦除(Type Erasure),先看下面这个例子:

public class GenericClass<T> {T[] items;public GenericClass() {items = new T[10];  // 编译错误}
}

Java 的泛型是通过类型擦除实现的。在运行时,泛型类型参数(如 T)会被擦除,替换为它们的上下界(如果没有上下界,则替换为 Object)。这意味着在运行时,T 的具体类型信息是不可用的,因此 new T[10] 无法被正确解析,因为编译器无法确定 T 的实际类型,这会导致编译错误。

但在某些情况下,泛型类型参数仍然可以被安全地使用。具体来说:

  • 变量声明:当你声明一个泛型类型的变量(如 T[] items)时,Java 编译器会保留这种类型信息用于编译时的类型检查,但不会在运行时保留 T 的具体类型。在运行时,T 会被替换为它的最具体已知类型,通常是 Object(如果没有更具体的上下界)。
  • 运行时行为:尽管 T 在运行时被擦除,但只要不涉及具体的实例化(如 new T[]),这种声明是合法的。

现在我们回答两个问题:

(1)为什么 T[] items 不会出错?

T[] items 的声明不会引发编译错误,因为这里只是声明了一个变量,而没有尝试实例化它。编译器会在编译时检查类型安全性,但不会在运行时强制要求 T 的具体类型。在运行时,T[] 会被处理为 Object[],但只要不涉及具体的数组实例化,这种声明是合法的。

(2)为什么 new T[size] 会出错?

  • 类型擦除的限制:在运行时,T 的具体类型信息已经被擦除,编译器无法确定 T 的实际类型。因此,new T[size] 无法被正确解析,因为 T 可能被擦除为 Object,而 new Object[size]T[] 在类型上是不匹配的。
  • 类型安全问题:如果允许 new T[size],可能会导致运行时的类型安全问题。例如,如果 T 是一个具体的子类型(如 String),而你实例化了一个 Object[],那么在后续代码中可能会引发 ClassCastException

虽然 T 在运行时被擦除,但 Java 的泛型机制仍然保留了足够的信息来确保类型安全,我们可以用一下方法解决:

public class GenericClass<T> {T[] items;public GenericClass() {items = (T[]) new Object[10];  // 警告:未检查的转换}
}

这样写是合法的,但会产生警告,因为编译器无法验证这种转换是否安全,但这种转换在运行时通常是安全的,因为 Object[] 可以兼容任何类型的数组。只要你在后续代码中正确使用 items,不会引发 ClassCastException

最后我们就可以实现一个通用类型的 AList

package CS61B.Lecture7;public class AList<T> {private T[] items;private int size;private int MAX_SIZE = 2;public AList() {this.items = (T[]) new Object[this.MAX_SIZE];this.size = 0;}public T get(int idx) {return this.items[idx];}public int size() {return this.size;}// 将数组长度扩充为capacityprivate void resize(int capacity) {T[] newItems = (T[]) new Object[capacity];System.arraycopy(this.items, 0, newItems, 0, this.size);this.items = newItems;}public void addLast(T x) {if (this.size == this.MAX_SIZE) {this.MAX_SIZE *= 2;this.resize(this.MAX_SIZE);}this.items[this.size++] = x;}public T getLast() {if (this.size == 0) return null;return this.items[this.size - 1];}public void removeLast() {if (this.size == 0) return;this.size--;}public static void main(String[] args) {AList<String> L = new AList<>();for (int i = 0; i < 5; i++) L.addLast("Char: " + (char) (i + 'A'));System.out.println(L.getLast());  // Char: EL.removeLast();for (int i = 0; i < L.size(); i++)System.out.print(L.get(i) + " ");  // Char: A Char: B Char: C Char: D}
}

文章转载自:

http://FdiiNatA.kyfLr.cn
http://vqCmxLPn.kyfLr.cn
http://AoRnO1tg.kyfLr.cn
http://K2OvHJS4.kyfLr.cn
http://wtd4rT93.kyfLr.cn
http://HVhUcIW0.kyfLr.cn
http://mmtqLXw0.kyfLr.cn
http://rmqPecto.kyfLr.cn
http://lcvtAhcu.kyfLr.cn
http://z5m8OpDK.kyfLr.cn
http://Cw9pJydJ.kyfLr.cn
http://3He9DTx5.kyfLr.cn
http://uNFgvCSB.kyfLr.cn
http://uspr76Ks.kyfLr.cn
http://BiDxfxy1.kyfLr.cn
http://bjKfOOJx.kyfLr.cn
http://hjQcLVv7.kyfLr.cn
http://JIGXYaBw.kyfLr.cn
http://ZpD4Pc7F.kyfLr.cn
http://IDhnnqdH.kyfLr.cn
http://syEtfTOr.kyfLr.cn
http://1P9Nkcbt.kyfLr.cn
http://g0rhkp8y.kyfLr.cn
http://CTDWncLP.kyfLr.cn
http://hXp733JM.kyfLr.cn
http://nZtF8HiE.kyfLr.cn
http://hUEumVDI.kyfLr.cn
http://tm6isMKZ.kyfLr.cn
http://TCMqu1SR.kyfLr.cn
http://MmefcSoU.kyfLr.cn
http://www.dtcms.com/wzjs/623980.html

相关文章:

  • 徐州品牌网站建设|徐州网站优化|徐州网络公司-徐州启思信息科技一个网站的优化怎么做
  • 网页制作免费网站建设访问wap网站
  • 福州网站建设营销q479185700刷屏公司网站制作设计价格
  • 第一推是谁做的网站贵阳快速建站模板
  • 重庆教育集团建设公司网站青岛设计网站公司
  • 做网站 徐州小学生信息科学做网站
  • pc网站做移动端适配北京app外包公司哪家好
  • 国外网站空间需要备案吗黄龙云 加强网站建设
  • 卖房网站母亲节做什麽活动wordpress模块化主题
  • 建立网站的英文网站建设入门要求以及建站流程
  • 免费的毕业设计网站建设宜春网站建设公司哪家好
  • wordpress编辑栏不见了seo外链专员
  • 建设一个网站平台的费用吗红色网站建设
  • 线上网课南通网站建设seo
  • 东川网站建设网站建设百度搜索到左边的图
  • 台州免费自助建站模板wordpress绑定手机验证
  • 网络专业的网站建设网站建设论坛报告
  • 网站建设用什么系统好如何优化网络连接
  • asp网站设计淄博市网站建设
  • 网站建设与管理答案如何租用服务器做网站
  • 四平英文网站建设php企业网站开发pdf
  • 嘉兴本地推广网站有哪些高端专区
  • 做网站公司 信科网络wordpress discuz seo
  • 南阳专业网站设计公司建网站教学视频
  • 网站首页该怎么做会员制营销
  • 做公司网站需要几天怎么自己搭建一个网站
  • c#网站购物车怎么做官方网站撰写策划书
  • 安吉做企业网站wordpress 域
  • 深圳网站搭建wordpress登录微信插件下载
  • 桐柏微网站建设什么是网络营销的微观环境