7数组
7.1数组的概念
案例:计算5名同学的平均分
var a1,a2,a3,a4,a5,a6,a7,a8,a9,a10;
a1 = Number(prompt("请输入分数"));
a2 = Number(prompt("请输入分数"));
a3 = Number(prompt("请输入分数"));
a4 = Number(prompt("请输入分数"));
a5 = Number(prompt("请输入分数"));
a6 = Number(prompt("请输入分数"));
a7 = Number(prompt("请输入分数"));
a8 = Number(prompt("请输入分数"));
a9 = Number(prompt("请输入分数"));
a10 = Number(prompt("请输入分数"));
var ave = (a1+a2+a3+a4+a5+a6+a7+a8+a9+a10)/10;
alert(ave);
这个程序很简单,但是如果100人呢,难道真的要复制100遍;
怎么解决?需要使用循环。但是尝试一下,循环使用不上,因为无法控制变量a1,a2也就是无法将循环控制变量和变量a1,a2l联系起来
var a = [];
var sum = 0;
for(var i=0; i<10; i++){
a[i] = Number(prompt("请输入分数"));
sum += a[i];
}
var ave = sum/ a.length
alert(ave);
这段代码能够实现同样的功能,而且如果是100人的话,只要把循环的条件改为i<100即可
整个程序的结构和代码量和人数没有关系。
为什么和人数没有关系?因为和循环结合起来了。
为什么能和循环结合起来呢?因为我们把变量的表示方式改变了,及名称+序号的方式(a[0]、a[1]……),那么序号是可以用循环变量去控制。
定义有三种方式
(1)var a = [];
(2)var a = new Array();
(3)var a = [0,0,0];
访问元素:数组名加下标
a[0] a[3];
需要注意的是下标从0开始
需要注意的是下标从0开始。
所以在使用的时候需要注意越界的问题,比如5个元素的数组,那么它的下标范围【0,4】,不包括5,5已经越界了。
数组的本质:一组数据(变量)的集合,或者说是一组内存单元。只不过对于变量的表示方式适应的是数组名+下标的方式。
7.3数组的常用属性和方法
数组的属性:
length:1告诉我们数组的长度:数组名.length
通过该属性可以改变数组的长度
数组的常用方法:
1)unshift在数组的头部添加元素,返回值返回的是新数组的长度
shift:删除数组的头部元素,返回值是删除的头部元素
2)indexOf:查找在数组中重复出现的元素第一次出现的位置,返回值是该元素的下标。
lastIndexOf:查找在数组中重复出现的元素最后一次出现的位置,返回值是该元素的下标。
3)push:在数组的尾部插入元素,返回值是添加元素后数组的长度。
pop从数组的尾部删除最后一个元素,返回值就删除的元素
4)slice(开始位置下标,结束位置的下标);提取数组中指定连续的字数组。前包括,后不包括。
5)splice(剪接)前面两个参数定义剪的部分,第三个参数定义接的的部分(开始位置的下标,要删除元素的快度,更选择插入和替换的内容):
1、删除操作:删除数组中指定的任意元素
2插入操作:可以在数组指定位置插入元素
3,替换操作:在数组中替换指定位置的元素
6)reverse:将数组中的元素,反序输出。在原数组的基础上进行反序输出,不会重新创建数组。
7)map:原数组的映射,经过函数的加工,返回给你一个新数组。
一般我们传递的参数都是数值,字符串类型的数据,有些时候可能需要传递一个函数,那如何传递一个函数呢?
函数名:函数的入口地址。
var a=[2,4,6,8];
var b = a.map(fun);
alert(b);
function fun(value,index,self){
return value*value;
};
我们可以将以上内容简写为:
var a=[2,4,6,8];
var b = a.map (function (value,index,self){
return value*value;
});
这就是匿名函数
7.4for in
student.age
student[“age”]
7.5数组的应用
(1)查找
indexof系统提供的
我们也可以实现自己的查找方式
var a = [3,7,11,43,87,5,99,22,53,8];
var n = Number(prompt("请输入要查找的值"));
var index = -1;//最初认为要找的数不在数组中
for(var i in a){
if(a[i] == n){
index = i;
break;
}
}
这种查找方法最简单,但是查找次数与数据量成正比,效率不高。
折半查找(二分查找)
假设在一个已经有序的数组中,可以利用折半查找大幅提高效率。
/*
* 思路
* (1)用start表示查找范围的起点,end表示终点
* (2)只要start<=end就重复步骤3
*(3) 比较中间位置(mid)的那个数进行比较
* a 相等:找到了,结束
* b 大于:在前半段找,即end=mid-1
* c 小于:在后半段找,即start=mid+1
* 4.输出结果
* */
var a = [3,5,7,8,11,22,43,51,87,89];
var n = Number(prompt("请输入要查找的值"));
var index = -1;//最初认为要找的数不在数组中
var start = 0;
var end = a.length-1;
while(start<=end){
var mid =Math.ceil((start+end))/2;//计算中间位置
if(n == a[mid]){
index = mid;
break;
}else{
if(n > a[mid]){
//在后半段找
start = mid+1;
}else{
//在前半段找
end = mid -1;
}
}
}
alert(index);
折半查找的最坏查找次数与数据量的关系,所以说它的查找效率
是很高的,但是任何事情往往都要两面性,它的高效率也是有高代价的,也是要求有序
(2)排序(冒泡排序)
var a = [3,5,77,57,11,68,2,99,23,18];
for( var i=0; i<=a.length-1; i++){
for(var j=0;j<=a.length-i-1;j++){
if(a[j] > a[j+1]){
var t = a[j];
a[j] = a[j+10];
a[j+1]=t;
}
}
}
alert(a.toString());
(3)队列
先进先出(FIFO),在头部出队(shift),在尾部入队(push)
(4)堆栈
先进后出(FIFO),在尾部进栈(push),在尾部出栈(pop),
8常见算法
8.1累加/累积
累加:将一系列的数据加到一个变量里面,最后得到累加的结果
比如:将1到100的数累加求和
小球从高处落下,每次返回到原来的一半,求第十次小球落地的时小球走过的路程
var h = 100;
var s= 0;
for(var i=0; i<10; i++){
h = h/2;
s += h;
}
s = s*2+100;
累积:将一列的数据乘积到一个变量里面,得到累加的结果。
常见的就是n阶乘。
var n = 100;
var result = 1;
for(var i=1;i<=100;i++){
result*=i;
}
一般形式:
累加:V += e;
累积:V *= e
V代表累加/累积,e代表累加/累积项
算法要点:
(1)初始化
初始化v和e
累加:V = 0;
累积:V = 1;
e的初始化,如果累加/积项比较复杂,可能会分解为几个子项分别初始化
比如计算圆周率的问题,累加项分解为符号、分子和分母三项
(2)循环的控制条件
(3)一种是固定次数,比如计算弹跳距离的问题、计算数列前20项之和的问题
次数不固定,而是要满足某个条件:计算圆周率问题要求最后一项的绝对值小于10-6
(4)确定累加/累/积项
(5)比如数列的前20项之和,是将当前的分子分母之和作为下一次的次的分母,当前的分母作为分子
再比圆周率问题,是将符号取反,分母2得出下一项。