如何增加数组长度和删去数组中的某个元素?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何增加数组长度和删去数组中的某个元素?相关的知识,希望对你有一定的参考价值。

C++,程序语言,计算机

想当初, 在我刚学习C++数组的时候就有个愿望,希望我能随心所欲地操作数组,当需要扩充数组时只要在原数组最后一个元素后面加新元素即可,而当我要删除一个元素时,元素会自动排列,然而随着深入学习,我才发现这是做不到的。

事实是,由于内存分配之后,后续空间可能会被占用,而对数组元素的要求是连续排列的,当然我们可以让系统在重新分配前对已分配内存进行分析,如果原数组后面内存为未占用且空间满足要求,则直接对数组扩容,如果后续空间已被占用,则只能另辟蹊径,重新分配内存并复制元素,然后释放掉原数组占用的空间,也许前辈们经过权衡,觉得这样做会增加计算开销还不如干脆点,直接进行重新分配内存更快捷。

而删除时,显然元素自己不会移动,只能用程序循环一个个移动字节.

由于固定长度的数组是无法释放的,除非程序结束,为了实现动态数组,实际上并不是数组本身是动态的,而是数组占用的内存是可以被释放的,只是我们是在运行时用new重新分配一块新空间(新的数组长度),并复制原来的元素,以代替原数组,从而实现数组长度的动态变化,而new返回的是地址,因此我们需要定义一个指针作为访问数组的标识符.
int ary[100];//这样定义的数组是无法释放和调整大小的.
int *pArray=new int(100);//定义时初始化100个元素
//其他代码
int *p=new int(120);//重新申请一块新的内存空间,指定的大小可以调整,赋值给中间指针变量P暂保管
memcpy(p,pArray,sizeof(int)*100);//调用内存复制函数复制原始数据
if (pArray)delete []pArray; //释放原数组内存空间
pArray=p;//替换指针
------------删除元素-----------------------------
int dIndex=50;//假设这是需要删除的元素索引
int arrayLength=100;//该变量记录数组长度
int dataLength=90;//该变量记录有效元素个数
for (int i=dIndex+1;i<dataLength;i++)
pArray[i-1]=pArray[i];
dataLength--;//注:原先打错了,不应该改变数组长度而是改变元素长度
从索引指向的后一个元素赋值给索引指向的位置,以覆盖掉要删除的元素,并将之后的其他元素逐个位移一个位置,其中数组空间调整(即动态分配)不要太频繁,否则影响效率,作为学习你也可以写一个类专门处理数组,当新增数据超过数组长度时再进行重新动态分配,每次步增一个定值,比如100,而如果未超过数组长度时,只递增数据长度变量用于跟踪。也就是每次动态分配要多给一点冗余/空白内存。所以要设计两个变量分别跟踪记录数组长度以及实际的元素长度.追问

也就是说,想要进行上述操作,需要重新分配一块内存,并把值复录进去?

追答

对,第一段我已经说明了,每个初学者都想当然的,其实从来就是重新分配空间替换原数组而不是对原数组扩展,原因开头已经说明,不经济.

追问

不知道这样能不能过老师那一关。

追答

放心吧,哪怕是Java,C#这些高级语言的list类,看上去好像是在原数组之上不断Add元素它会自增,可实际上其内部已经帮你实现了重新分配内存的功能,实际上任何语言实现动态数组都是这个机制,你也可以用C++实现一个可以自己调整容量的类。这就是封装

知道为什么电脑手机使用时间长了会出现垃圾内存吗?除了一些软件没做好内存释放存在内存泄漏之外,余下的原因就是因为内存不断被各种应用申请释放而形成大量内存碎片,然后后面的软件需要申请内存是找不到可以容纳其需要的容量出现等待而卡顿,虽然有些工具号称可以对内存碎片整理,类似硬盘碎片,但实际上效果不佳,因为由第三方软件改动内存位置系统是不允许的,内存是受系统保护的,即便系统允许也很容易出现问题,因为地址改变了,软件中指针也需要被改变,而软件是运行中的,第三方工具很难与一个应用做好信息沟通容易出现死机

所以运行时间长了后卡顿了,一般重启一下都可以解决

本质上就是无论是加载一个软件执行还是一个软件在运行中申请一块内存,系统都是找一块可以容纳下所申请的容量的连续内存块给程序,而不是东拼西凑找一些碎片给程序,那样的话系统用于记录内存占用情况的表就不够用,而且软件访问时非常麻烦,试想一下一个4字节的int变量存在两块内存的奇怪情况,那一个变量需要记录两个地址,并且还要记录两块内存的拼装情况,这完全不可接受的

参考技术A 数组都是用new获取,用delete []释放,有一个特定变量记录数组元素个数
新申请一个新的合适长度的数组,
然后将原数组中数复制过来,
释放原数组
将新的数组首指针赋值给原数组指针
记录新的数组长度到特定变量,替换原值

js中常用的数组方法

  • 在数组的尾部增加或删除某个元素:push() 和 pop()

  push() : 在数组的尾部追加一个或多个元素,并返回数组的长度

  pop():在数组的尾部删除一个元素,并返回被删除项

1 var arr = ["aaa","bbb","ccc"];
2 var pushRes = arr.push("ddd","eee");
3 console.log(pushRes); // 5 (返回新数组的长度) 
4 console.log(arr); // ["aaa", "bbb", "ccc", "ddd", "eee"]
5 var popRes= arr.pop();
6 console.log(popRes); // eee
7 console.log(arr); // ["aaa", "bbb", "ccc", "ddd"]
  • 在数组的头部增加或删除某个元素:unshift() 和 shift() 

  unshift() : 在数组的头部插入一个或多个元素,并返回数组的长度

  shift():在数组的头部删除一个元素,并返回被删除项

1 var arr = ["aaa","bbb","ccc"];
2 var unshiftRes = arr.unshift("ddd","eee");
3 console.log(unshiftRes); // 5 (返回新数组的长度) 
4 console.log(arr); // [ "ddd", "eee", "aaa", "bbb", "ccc"] 
5 var shiftRes= arr.shift(); 
6 console.log(shiftRes); // ddd 
7 console.log(arr); // ["eee", "aaa", "bbb", "ccc"]
  • 截取数组slice()

  slice(截取的起始位置,截取的结束位置)  slice可以有两个参数,第一个参数为必填项,第二个参数为选填项,当只有一个参数的时候,默认截取到数组的末尾;此外第二个参数可以有正数和负数两种情况,若第二个参数为负数截取的结束位置从末尾倒数过来

1 var arr = [1,2,3,4,5];
2 var arr1 = arr. slice(1);
3 var arr2 = arr. slice(1,3);
4 var arr3 = arr. slice(1,-1);
5 var arr4 = arr. slice(-3,-1);
6 console.log(arr1);   //[2,3,4,5]
7 console.log(arr2);   //[2,3]
8 console.log(arr3);   //[2,3,4]
9 console.log(arr4);   //[3,4]
  • 数组万能法splice() 

  splice():很强大的数组方法,它有很多种用法,可以实现删除、插入和替换。

  删除:可以删除任意数量的项,只需指定 2 个参数:要删除的第一项的位置和要删除的项数。例如, splice(0,2)会删除数组中的前两项。

  插入:可以向指定位置插入任意数量的项,只需提供 3 个参数:起始位置、 0(要删除的项数)和要插入的项。例如,splice(2,0,4,6)会从当前数组的位置 2 开始插入4和6。
  替换:可以向指定位置插入任意数量的项,且同时删除任意数量的项,只需指定 3 个参数:起始位置、要删除的项数和要插入的任意数量的项。插入的项数不必与删除的项数相等。例如,splice (2,1,4,6)会删除当前数组位置 2 的项,然后再从位置 2 开始插入4和6。

  splice()方法始终都会返回一个数组,该数组中包含从原始数组中删除的项,如果没有删除任何项,则返回一个空数组。

 1 var arr = [1,3,5,7,9,11];
 2 var arrRemoved = arr.splice(0,2);
 3 console.log(arr); //[5,7, 9, 11]
 4 console.log(arrRemoved); //[1,3]
 5 var arrRemoved2= arr.splice(2,0,4,6);
 6 console.log(arr); //[5, 7, 4, 6, 9, 11]
 7 console.log(arrRemoved2); //[]
 8 var arrRemoved3 = arr.splice(1,1,2,4);
 9 console.log(arr); //[5, 2, 4, 4, 6, 9, 11]
10 console.log(arrRemoved3); //[7]
  • 数组遍历forEach()
 1 var arr = [1,2,3,4,5]
 2 arr.forEach(function(item,index){
 3     console.log(index,item)   
 4 })
 5 //输出结果为:
 6 //0 1
 7 //1 2
 8 //2 3
 9 //3 4
10 //4 5
  • 映射方法:map()
1 var arr = [1,2,3,4,5];
2 var arr2 = arr.map(function(item){
3     return item+10;
4 });
5 console.log(arr2); //[11,12,13,14,15]

 






以上是关于如何增加数组长度和删去数组中的某个元素?的主要内容,如果未能解决你的问题,请参考以下文章

java 数组添加一个或多个元素

java中如何初始化对象数组,并增加元素

如何从一个数组中查找指定的元素,并返回这个元素在数组中的位置

找数组中重复次数超过数组长度一半的元素

js如何创建一个数组并给数组设置指定宽度

Dart数据类型--List (数组)及其相关操作