数组
数组基础
PHP中,数组的下标可以是整数或字符串。(注意:数组的元素不是由下标决定,而是由其“加入”的顺序决定)
定义形式:
array(1, 5, 1.1, "abc", true, false); //可以存储任何数据,此时“默认下标”
array(2=>1, 5=>5, 3=>1.1, 7=>"abc", 0=>true);//下标可以任意设定,无需顺序,无需连续
array(2=>1, 5, 1=>1.1, "abc", 0=>ture) //可以加下标,可以使用默认下标
//默认下标规则:前面使用过的最大数字下标加1,该数组下标为:2,3,1,4,0
array(2=>1, "dd"=>5, 1=>1.1, "abc", 0=>true);//混合下标同样遵循默认下标规则
array(-2=>1, "dd"=>5, 1.1, "abc", true);//负数小标当做字符串,则最后三项下标为0,1,2
array(2.7=>1, "dd"=>5, 1=>1.1, "abc", 0=>true);//浮点数下标会自动转换为整数且去掉小数
array("2.7"=>1, "dd"=>5, "11"=>1.1, "abc", true);//纯数字字符串下标当做数字看待
//则此时下标为:2,“dd”,11,12,13
array(2=>1, "dd"=>5, true=>1.1, "abc", false=>true);//布尔值为下标,则true为1,false为0
array(2=>1, "dd"=>5, 2=>1.1, "abc", true); //如果下标跟前面的重复,
//则只是单纯覆盖前面同名下标的值
//此时相当于Array(2=>1.1, “dd”=>5, ”abc”, true);
其他形式:
$arr1[] = 1;
$arr1[] = 5;
$arr1[] = 1.1; //直接在变量后面使用[],其转化为数组并依次赋值
$arr1['aa'] = 1;
$arr1[5] = 1.1; //此种语法符合array()语法结构
取值:
- 通过下标直接取值
- 通过指针操作函数直接取得对应数据
赋值:赋值即定义
数组的分类
从键值关系:
- 关联数组:通常指下标为字符串并且该字符串大体能表达出数据的意义的数组
$person = array(
"name"=>"小明",
"age"=>18
);
- 索引数组:通常指下标严格由0连续排列的数组,js中的数组只能这样。
从数组的层次来分
一维数组:数组中的每一个元素都为普通值(非数组)
二维数组:数组中的每个元素都为一个一维数组,如:
$arr1 = (array(1, 2, 3), array(1, 3), array(1));
多维数组:数组中的每个元素都为若干个数组嵌套而成的数组,取值为:$v1 = 数组名[下标1][下标2][......]
数组函数
在PHP中,有许多函数都为数组而生,它们能完成各种各样的功能且算法效率比较高
- 指针操作函数:current、key、next、prev、reset、end、each
- 单元操作函数:array_pop、array_push、array_shift、array_unshift、array_slice、array_splice
- 排序函数:sort、asort、ksort、usort、rsort、arsort、krsort、shuffle
- 查找函数:in_array、array_key_exists、array_search
- 其他函数:count、array_reverse、array_merge、array_sum、array_key、array_values、array_map、array_walk、range
数组遍历
遍历基本语法
foreach($arr as [$key =>]$value){ //括号中部分可省略
//进行对$key和$value的操作,$key为每次取得的元素下标,可能是数字或字符串
//$value:每次取得的元素
//此循环结构从第一项一直遍历到最后一项
}
数组指针和遍历原理
数组内部有一个指针,该指针决定数组当前取值的时候取到的元素,foreach遍历过程中,指针从第一项依次往后直到最后一项
指针除了赋值foreach循环的位置设定外,还有一些函数也依赖于指针
- $v1 = current($arr1); //取得$arr1中当前指针指向的元素,如果没有指向元素返回false
- $v1 = key($arr1); //取得$arr1中当前指针所指向的元素下标,没有指向元素则返回false
- $v1 = next($arr1); //将指针移向”下一个元素“,然后取得该下一个元素的值
- $v1 = prev($arr1); //将指针移向“上一个元素”,取得上一个元素的值
- $v1 = reset($arr1); //将指针移向“第一个元素”,然后取得该元素的值
- $v1 = end($arr1); //将指针移向“最后一个元素”并取得该元素的值
- $v1 = each($arr1); //取得当前元素的下标和值并移动指针到下一个位置
数组遍历的流程图:
for+next+reset遍历数组
reset($arr1); //重置数组:即数组初始化,返回的数据丢弃
$len = count($arr1);
for($i = 0; $i<$len; ++$i){
$key = key($arr1);
$value = current($arr1);
//对下标和值的操作
next($arr1); //移动指针到下一个元素
}
求奇数偶数的和简单
while+each()+list()遍历数组
each()函数解释:
each()函数可取得一个数组中的元素下标和值并放入一个新的数组中,指针后移一位。此新的数组中含有4个元素,存储的数下标和值的双份:形式:array(1=>取出来的值,’value’=>取出来的值,0=>取出来的下标,’key’=>取出来的下标);
list()语言结构(不是函数)解释:
使用形式:list($v1, $v2, $v3, $v4, ...) = 数组arr1;
作用:依次取得数组$arr1中下标为0,1,2,3,...的元素并一次性放入多个元素中。$v1 = $arr1[0]; $v2 = $arr1[1]; ....
注意:只能实现这样的“从0开始”的连续数字的取值(并非要求数组元素的下标顺序为0,1,2,3,...)
使用这2个函数和while循环结构来实现数组遍历:
reset($arr1);
while(list($key, $value) = each(arr1)){ //从数组中一次次取得元素并赋给相应变量
//操作
}
foreach遍历细节探讨
foreach为正常的循环语法结构,可以有break和continue等操作。
遍历过程值变量可认为设定为引用传递(默认为值传递)
- foreach($arr as $key => &$value){}
- 键变量不可设定为引用传递
foreach默认是在原数组上进行遍历,如果在遍历过程中对数组进行了某种修改或指针性操作,则会复制原数组在原来的数组上进行操作
foreach中如果值变量为引用传递,则无论怎样都在原数组上进行
数组排序思想介绍
冒泡排序
目标:将数组进行正序或逆序排列。
$arr2 = array(5, 15, 6, 8, 4);
排序过程描述:
1,对该数组从第一个元素开始,从左到右,相邻的2个元素比较大小:如果左边的比右边大,则将它们交换位置:
array(5, 15, 6, 8, 4); //初始5个元素进行4次循环
array(5, 6, 15, 8, 4); //5与16进行比较并安排顺序
array(5, 6, 8, 15, 4);
array(5, 6, 8, 4, 15);
此时进入第二趟循环:
array(5, 6, 8, 4, 15); //此时最右边的值已为最大值,相当于为左边4个数进行排序,3次循环即可
array(5, 6, 8, 4, 15); //依次类推
array(5, 6, 4, 8, 15);
此时进入第三趟循环:
array(5, 6, 4, 8, 15);
array(5, 4, 6, 8, 15);
此时进入第四趟循环:
array(4, 5, 6, 8, 15);
逻辑描述:(假设数组有n项)
- 需要进行n-1趟的“冒泡”排序过程
- 每一趟的比较都比以前少1趟,第一趟为n-1次
- 每次比较都是从数组的开头跟相邻的元素比较并选择是否交换
选择排序
目标:将下列数组进行正序排列。
$arr2 = array(5, 15, 6, 8, 4);
一般性描述:
- 取得该数组中的最大值及其下标并跟数组的最后一项“交换”
- 取得该数组中除最后一项的最大值及其下标并跟倒数第二项交换
- 取得该数组中除最后两项的最大值及其下标并跟倒数第三项交换
- 取得该数组中除最后三项的最大值及其下标并跟倒数第四项交换
最初 | 5 | 15 | 6 | 8 | 4 |
第1趟 | 5 | 4 | 6 | 8 | 15 |
第2趟 | 5 | 4 | 6 | 8 | 15 |
第3趟 | 5 | 4 | 6 | 8 | 15 |
第4趟 | 4 | 5 | 6 | 8 | 15 |
逻辑描述:(假设数组有n项)
- 进行n-1趟才能得出结果
- 每一趟找的数据都比前一趟少一个,第一趟要找n个
- 每次找出最大值所在的项,每次进行交换的位置依次减1,第一次的位置为n-1
数组查找
从数组找相应的数据(数据或下标),所研究的问题无非2个
- 判断数据是否存在
- 找出相应数据的位置(下标)
顺序查找
按照顺序找出相应信息
1,判断数据是否存在
$v1 = 10;
function search($arr, $v1){
foreach($arr as $value){
if($v1 == $value)
return true;
}
return false;
}
2,找出数据的位置
$v1 = 10;
function search($arr, $v1){
foreach($arr as $value){
if($v1 == $value)
return $key;
}
return false;
}
//注意一下调用该函数的用法
if($m = search($arr, 10) === false) //这里用全等因为以0位下标返回的值会导致错误
echo "没找到";
else
{
}
二分查找:
前提:数组已经排序OK,下标索引连续。
思路如下:对于一个很长的数组,在查找数据时,可先将数组的中位值与其比较,(假设该数组为正序排列的数组)当该中位值大于查找的数据时,说明如果该查找数据存在的话只可能存在在数组的前半部分,这样可把前面一半的数据看成一个独立的数组,这样查找数据的范围就减少了一半,依次类推.......,查找到最后时,若该数组中有与其相等的值直接退出返回其下标,否则到最后查找的数组的最后的下标会小于首下标则退出,返回该数据不存在该数组中(建议用递归解决该问题)
递归函数逻辑模型如下:
function search(数组名, 要查找的数据, 数组的头下标, 数组的尾下标){
if(数组的头下标 > 数组的尾下标)
return 查找不到数据;
//1,取中位值的下标(利用头下标和尾下标)
//2,比较中位值和查找的数据
if(中位值 == 查找的数据)
return 对应的下标
else if(中位值 > 查找的数据){
//将头下标和尾下标改变
return function search(数组名, 要查找的数据, 数组的头下标, 数组的尾下标);
}
else
{
//将头下标和尾下标改变
return function search(数组名, 要查找的数据, 数组的头下标, 数组的尾下标);
}
}