數(shù)組的分類(lèi)、定義
索引數(shù)組(就是js數(shù)組的下標(biāo)情況嘛,下標(biāo)為從0開(kāi)始的連續(xù)整數(shù))、關(guān)聯(lián)數(shù)組、混合數(shù)組
數(shù)組定義有很多種方法,都是小問(wèn)題啦。
數(shù)組定義.PNG
要注意的是,php數(shù)組的元素順序,和下標(biāo)沒(méi)有任何關(guān)系!只與放入的順序有關(guān)!
數(shù)組的基本使用
1.求一維數(shù)組的平均值;求二維數(shù)組平均值也類(lèi)似
//1.求一維數(shù)組的平均值
<?php
header("charset=UTF-8");
$arr1 = array(10, 20, 30, 40, 50);
$len = count($arr1);
$num = 0;
$sum = 0;
for($i = 0; $i < $len; $i ++){
$sum += $arr1[$i];
++ $num;
}
echo "平均值:" . ($sum/$num); //30
?>
2.求一維數(shù)組的最大值及其下標(biāo)
//求一維數(shù)組的最大值(索引數(shù)組)
$arr2 = array(3, 11, 1, 4, 23, 19);
$max = $arr2[0];
$pos = 0;
for($i = 1; $i < count($arr2); $i ++){
if($max < $arr2[$i]){
$max = $arr2[$i];
$pos = $i;
}
}
echo "最大值為$max";
echo "下標(biāo)為$pos";
數(shù)組的遍歷
1.foreach基本語(yǔ)法
for($數(shù)組變量名 as $key => $value){
//$key => 可省略
//循環(huán)體可以使用 $key 和 $value
//總從數(shù)組的開(kāi)頭往后取數(shù)據(jù)
}
2.指針操作及遍歷原理
- 默認(rèn)情況下,數(shù)組指針指向數(shù)組第一個(gè)單元
- 數(shù)組有關(guān)單元的操作,如果沒(méi)有指定下標(biāo),就是對(duì)該數(shù)組指針?biāo)鶎?duì)應(yīng)單元的操作
所謂遍歷,其實(shí)就是指針一次次地下移,且一次次地取鍵和值。數(shù)組作為一個(gè)總體數(shù)據(jù),有以下這些指針操作函數(shù):
//1.獲得數(shù)組當(dāng)前指針?biāo)趩卧闹?$v1 = current($arr);
//2.獲得數(shù)組當(dāng)前指針?biāo)趩卧逆I
$v2 = key($arr);
//3.先將數(shù)組的指針移到下一個(gè),然后取新的單元的值
$v3 = next($arr);
//4.先將數(shù)組的指針移到上一個(gè),然后取新的單元的值
$v4 = prev($arr);
//5.先將數(shù)組的指針移到最后一個(gè)單元,然后取該單元的值
$v5 = end($arr);
//6.重置數(shù)組的指針重置到第一個(gè)單元,然后取該單元的值
$v6 = reset($arr);
3.for + next 遍歷數(shù)組
對(duì)php數(shù)組,不能單純用for循環(huán)遍歷,for循環(huán)只能遍歷索引數(shù)組呢。對(duì)于不是索引數(shù)組地?cái)?shù)組,要用for循環(huán)來(lái)遍歷地話(huà),要配合next來(lái)使用
$arr = array(1=>3, "a"=>5, 10=>22, "abc"=>9);
for($i = 0; $i < count($arr); $i ++){
$k = key($arr);
$v = current($arr);
echo $k . "=" . $v . "<br>";
//將指針下移
next($arr);
}
4.while + each() + list()遍歷數(shù)組
each()的作用:
先取數(shù)組當(dāng)前單元的下標(biāo)和值,并放到一個(gè)數(shù)組里,然后將指針移到下一位。
each().PNG
list()的作用:
一次性取得一個(gè)數(shù)組中,從0開(kāi)始的多個(gè)數(shù)字下標(biāo)的單元的值
$list($變量1, $變量2, $變量3, ...) = $數(shù)組,如果某個(gè)變量對(duì)應(yīng)的下標(biāo)沒(méi)有相應(yīng)的數(shù)組元素,會(huì)報(bào)錯(cuò)的。{比如$list($v1, $v2, $v3)=$arr,而數(shù)組$arr中沒(méi)有下標(biāo)為2的元素,則會(huì)報(bào)錯(cuò) }
$arr = array(1=>3, "a"=>5, 10=>22, "abc"=>9, 0=>12);
list($v1, $v2) = $arr;
echo $v1 . "和" . $v2; //12、3
while + each() + list() 組合使用遍歷
這個(gè)寫(xiě)法的作用和foreach完全一樣,所以學(xué)這個(gè)干啥?
while(list($key, $value)=each($arr)){
echo "$key=>$value";
}
5.foreach的一些細(xì)節(jié)
- 從php7開(kāi)始,foreach不再對(duì)數(shù)組內(nèi)部指針起作用,指針不會(huì)再移動(dòng)了,永遠(yuǎn)在初始狀態(tài)
- foreach也是正常的循環(huán)語(yǔ)法,break、continue等也是起同樣的作用的
- 遍歷過(guò)程中,值變量的默認(rèn)傳遞方式是值傳遞
- 遍歷過(guò)程中,值變量傳遞方式可以設(shè)置成引用傳遞,加上 &
$arr = array(1=>3, "a"=>5, 10=>22, "abc"=>9, 0=>12); foreach($arr as $key => &$value){ $value = $value *2; //改變值 echo "$key : $value <br>"; } print_r($arr); //輸出數(shù)組的值確實(shí)較之前改變了 - 鍵變量不可引用傳遞
- foreach默認(rèn)在原數(shù)組上進(jìn)行遍歷;若果遍歷過(guò)程中對(duì)數(shù)組進(jìn)行某種修改、或者某種指針性操作,則會(huì)復(fù)制數(shù)組后再?gòu)?fù)制出來(lái)的數(shù)組上進(jìn)行遍歷(即即使在遍歷過(guò)程中對(duì)數(shù)組進(jìn)行修改,但是遍歷過(guò)程還是按原來(lái)的數(shù)組來(lái)走,不受影響)
$arr = array(1=>3, "a"=>5, 10=>22, "abc"=>9, 0=>12);
foreach($arr as $k => $v){
echo "$k=>$v <br>";
if($k === 10){
$arr[99] = '新的數(shù)據(jù)項(xiàng)';
//添加一個(gè)新項(xiàng)到數(shù)組末尾
//但新項(xiàng)在這次遍歷中不會(huì)出現(xiàn)
}
}
//1=>3 a=>5 10=>22 abc=>9 0=>12
- 若果值變量是引用傳遞,則遍歷無(wú)論如何都會(huì)在原數(shù)組上進(jìn)行。
$arr = array(1=>3, "a"=>5, 10=>22, "abc"=>9, 0=>12);
foreach($arr as $k => &$v){
echo "$k=>$v <br>";
if($k === 10){
$arr[99] = '新的數(shù)據(jù)項(xiàng)';
//添加一個(gè)新項(xiàng)到數(shù)組末尾
//新項(xiàng)在這次遍歷中會(huì)出現(xiàn)!
}
}
//1=>3 a=>5 10=>22 abc=>9 0=>12 99=>新的數(shù)據(jù)項(xiàng)
數(shù)組排序函數(shù)
1.sort()
將數(shù)組的值從小到大排列,并且下標(biāo)全部改為索引下標(biāo)
2.asort()
將數(shù)組的值從小到大排列,下標(biāo)不會(huì)變
3.rsort()
從大到小排,下標(biāo)不保持
4.arsort()
從大到小拍,下標(biāo)保持不變
5.ksort()
按鍵名從小到大排
6.krsort()
按鍵名從大到小排
(更多見(jiàn)手冊(cè)啦)
冒泡排序算法
$arr = array(5, 1, 7, 6, 2);
//對(duì)數(shù)組 $arr 進(jìn)行冒泡從小到大排序
for($i = 0; $i < count($arr) - 1; ++ $i){//需要進(jìn)行 count($arr)-1 趟比較
for($k = 0; $k < count($arr) - 1 - $i; ++ $k){//每趟需要比較的次數(shù)
//把$k當(dāng)作下標(biāo)來(lái)使用
if($arr[$k] > $arr[$k + 1]){
//進(jìn)行交換
$t = $arr[$k];
$arr[$k] = $arr[$k + 1];
$arr[$k + 1] = $t;
}
}
}
print_r($arr);
選擇排序算法
$arr = array(3, 5, 22, 9, 12);
$n = count($arr);
//對(duì)數(shù)組 $arr 進(jìn)行冒泡從小到大排序
for($i = 0; $i < $n - 1; ++ $i){//需要進(jìn)行 count($arr)-1 趟交換
//每趟都要求出剩余數(shù)據(jù)中的最大值單元
$max = $arr[0];
$pos = 0;
for($k = 0; $k < $n - $i; ++ $k){//每趟的數(shù)據(jù) count($arr) - $i
if($arr[$k] > $max){
$max = $arr[$k];
$pos = $k;
}
}
//每一趟都要進(jìn)行交換,將最大值單元交換到剩余數(shù)據(jù)末位
$t = $arr[$pos];
$arr[$pos] = $arr[$n - $i - 1];
$arr[$n - $i - 1] = $t;
}
print_r($arr);
數(shù)組二分查找算法
- 針對(duì)索引數(shù)組
- 針對(duì)已經(jīng)排好序的數(shù)組(一般從小到大)
- 效率非常高,即使幾十億的數(shù)據(jù),也僅僅需要約30次就能找出來(lái)了
//已經(jīng)sort好的數(shù)組
$arr = array(3, 5, 9, 12, 14, 21, 33, 35, 39, 41, 45, 57, 67, 78, 87, 91, 95, 96, 233, 455, 655, 677, 689);
//查找數(shù)組中有沒(méi)有33這個(gè)項(xiàng)
$search = 1;
$len = count($arr); //數(shù)組長(zhǎng)度
//函數(shù)功能:在數(shù)組$array的$begin到$end位置之間找$target,返回到底有沒(méi)有$target
function binary_search($array, $target, $begin, $end){
//若果位置不合法,則不進(jìn)行查找
if($end < $begin){
return "不存在";
}
//位置合法,進(jìn)行查找
$mid = floor(($begin + $end)/2); //向下取整,得中間位置
$mid_val = $array[$mid];
if($mid_val == $target){
return "存在";
}
else if($mid_val > $target){
//中間項(xiàng)比目標(biāo)大,則繼續(xù)往中間項(xiàng)的左邊找
$result = binary_search($array, $target, $begin, $mid-1);
}
else{
//中間項(xiàng)比目標(biāo)小,則繼續(xù)往中間項(xiàng)的右邊找
$result = binary_search($array, $target, $mid+1, $end);
}
return $result;
}
//運(yùn)行函數(shù)
//在數(shù)組$arr中查找$search,在其全部位置中找(0到$len-1)
$v = binary_search($arr, $search, 0, $len-1);
echo $v;