PHP 第2章 数组 PHP 第2章 数组

2016-07-09

一、数组的查找

1.1、顺序查找

https://file.lulublog.cn/images/3/2022/08/DGh27hmBVOOZ77o5qJCC4gm0eOHT7v.jpg

1.2、二分查找

①、基本概念

前提,数组本身已经是有序数组了

首先找到数组中间的数,若要查找的数大于中间的数,则应向后查找,否则向前查找。

②、代码

function binarySearch(&$arr,$findlVal,$leftInde,$rightIndex)
{
    //当$leftIndex > $rightIndex 说明没有数了
    if($leftIndex > $rightIndex){
        return "找不到该数";
    }
    //找到中间的数
    $middleIndex = round(($leftIndex + $rightIndex)/2);
    //如果大于则往后面查找
    if($findVal > $arr[$middleIndex]){
        bingarySearch($arr,$findVal,$middleIndex+1,$rightIndex);
    }
    //如果小于则往前面查找
    if($findVal < $arr[$middleIndex]){
        bingarySearch($arr,$findVal,$leftIndx,$middleIndex-1);
    }else{
        return "找到这个数,下标=$middleIndex";
    }
}

二、数组的排序

2.1、排序的两大类

https://file.lulublog.cn/images/3/2022/08/JkY8ceEKhluEhsH77EEC4EctijHkYe.png

2.2、冒泡排序法

①、基本思想

https://file.lulublog.cn/images/3/2022/08/kKK601uxd6OJUzfoUfzUJjKYFuO6uI.png

②、案例分析:从小到大排序

https://file.lulublog.cn/images/3/2022/08/yj3arfJVASQvBDFB3d53FZRvFsd5bV.png

https://file.lulublog.cn/images/3/2022/08/AiiI2Fa20E2amgByP2PwtemMzFaA22.png

2.3、选择排序法

①、基本思想

https://file.lulublog.cn/images/3/2022/08/HBghqh6QhNdC8Z8BbGNn6nND2BggS5.png

②、案例分析:从小到大排序

https://file.lulublog.cn/images/3/2022/08/xd1Ay5skCCZA01KcD1SaSd0VsV1FaC.png

https://file.lulublog.cn/images/3/2022/08/wXEObBObLgfXpXG3xLCUcZCzEs5PS3.png

2.4 、插入排序法

分三种:插入排序法、希尔排序法、二叉树排序法

①、基本思想

https://file.lulublog.cn/images/3/2022/08/uA1gYgB38igaG3OYZA14W3iHHw4G55.png

②、案例分析

function insertSort(&$arr)
{
    //先默认下表为0这个数已经有序
    for($i=1;$i=0 && $insertVal<$arr[$insertIndex]){
            //把较大的数后移
            $arr[$insertIndex+1] = $arr[$insertIndex];
            $insertIndex--;
        }
        //插入(这时为$indexVal找到适当的位置了)
        $arr[$insertIndex+1] = $insertVal;
    }
}

https://file.lulublog.cn/images/3/2022/08/q88zEtIZiJtjeR7izslEEJJ8Ehn8h8.png

2.5、快速排序法

https://file.lulublog.cn/images/3/2022/08/b32xHD9U22R9i9N79R9XhrUS3Iui2w.png

https://file.lulublog.cn/images/3/2022/08/IK8IXEI3xaARbEQx8KLzeqzkkikA3g.png

2.6、总结

①、数组默认传递的是值,不是地址。如果要传递地址 ,用&

②、从效率上看:冒泡排序法 > 选择排序法 > 插入排序法

2.7、写一个二维数组排序算法函数,能够具有通用性,可以调用php内置函数

//二维数组排序, $arr是数据,$keys是排序的健值,$order是排序规则,1是升序,0是降序
function array_sort($arr, $keys, $order=0) {
    if (!is_array($arr)) {
    return false;
  }
  $keysvalue = array();
  foreach($arr as $key => $val) {
    $keysvalue[$key] = $val[$keys];
  }
  if($order == 0){
    asort($keysvalue);
  }else {
    arsort($keysvalue);
  }
  reset($keysvalue);
  foreach($keysvalue as $key => $vals) {
    $keysort[$key] = $key;
  }
  $new_array = array();
  foreach($keysort as $key => $val) {
    $new_array[$key] = $arr[$val];
  }
  return $new_array;
}

三、数组的系统函数

3.1、array_slice 和 array_splice

①、array_slice

array_slice ( array $array , int $offset [, int $length = NULL [, bool $preserve_keys = false ]] )

返回数组中指定下标offset和长度length的子数组切片。

——参数说明:设数组的长度为num_in。

  • offset

如果offset是正数且小于length,则返回数组会从offset开始;如果offset大于length,则不操作,直接返回。如果offset是负数,则offset = num_in+offset,如果num_in+offset == 0,则将offset设为0。

  • length

如果length小于0,那么会将length转为num_in - offset + length;否则,如果offset+length > array_count,则length = num_in - offset。如果处理后length还是小于0,则直接返回。

  • preserve_keys

默认是false,默认不保留数字键值原顺序,设为true的话会保留数组原来的数字键值顺序。

——使用实例

$input = array("a", "b", "c", "d", "e");
$output = array_slice($input, 2); // returns "c", "d", and "e"
$output = array_slice($input, -2, 1); // returns "d"
$output = array_slice($input, 0, 3); // returns "a", "b", and "c"
print_r(array_slice($input, 2, -1)); // array(0 => 'c', 1 => 'd');
print_r(array_slice($input, 2, -1, true)); // array(2 => 'c', 3 => 'd');

②、array_splice

array_splice ( array &$input , int $offset [, int $length = 0 [, mixed $replacement = array() ]] )

删除input中从offset开始length个元素,如果有replacement参数的话用replacement数组替换删除掉的元素。

——参数说明

  • array_splice函数中的offset和length参数跟array_slice函数中的用法一样。

  • replacement

如果这个参数设置了,那么函数将使用replacement数组来替换。如果offset和length指定了没有任何元素需要移除,那么replacement会被插入到offset的位置。如果replacement只有一个元素,可以不用array()去包着它。

——使用示例

$input = array("red", "green", "blue", "yellow");
array_splice($input, 2);
// $input变为 array("red", "green")
$input = array("red", "green", "blue", "yellow");
array_splice($input, 1, -1);
// $input变为 array("red", "yellow")
$input = array("red", "green", "blue", "yellow");
array_splice($input, 1, count($input), "orange");
// $input变为 array("red", "orange")
$input = array("red", "green", "blue", "yellow");
array_splice($input, -1, 1, array("black", "maroon"));
// $input为 array("red", "green","blue", "black", "maroon")
$input = array("red", "green", "blue", "yellow");
array_splice($input, 3, 0, "purple");
// $input为 array("red", "green","blue", "purple", "yellow");

3.2、reset、end、prev、current、next

reset() 将数组的内部指针倒回到第一个单元并返回第一个数组单元的值,如果数组为空则返回 FALSE
end() 函数将数组内部指针指向最后一个元素,并返回该元素的值(如果成功)。
prev()返回数组内部指针指向的前一个单元的值,或当没有更多单元时返回FALSE。
current ( array &array ) current() 函数返回当前被内部指针指向的数组单元的值,并不移动指针。如果内部指针指向超出了单元列表的末端,current()返回 FALSE。
next ( array &array ) 返回数组内部指针指向的下一个单元的值,或当没有更多单元时返回 FALSE。

3.3、sort、rsort、asort、arsort、ksort、krsort

sort() 函数用于对数组单元从低到高进行排序。
rsort() 函数用于对数组单元从高到低进行排序。 
asort() 函数用于对数组单元从低到高进行排序并保持索引关系。 
arsort() 函数用于对数组单元从高到低进行排序并保持索引关系。 
ksort() 函数用于对数组单元按照键名从低到高进行排序。 
krsort() 函数用于对数组单元按照键名从高到低进行排序。
  • bool sort( array &array [, int sort_flags] ) 可选参数 sort_flags 用于改变排序的行为:

sort_flags 取值 说明

SORT_REGULAR 正常比较单元 
SORT_NUMERIC 单元被作为数字来比较 
SORT_STRING 单元被作为字符串来比较 
SORT_LOCALE_STRING 根据当前的区域(locale)设置来把单元当作字符串比较

3.4、explode、implode

explode() 函数把字符串打散为数组
implode() 函数返回由数组元素组合成的字符串

3.5、array_chunk

array_chunk(array,size,preserve_key); 把数组分割为新的数组块
其中每个数组的单元数目由 size 参数决定。最后一个数组的单元数目可能会少几个
可选参数 preserve_key 是一个布尔值,它指定新数组的元素是否有和原数组相同的键(用于关联数组),还是从 0 开始的新数字键(用于索引数组)。默认是分配新的键。

3.6、说出数组涉及到的常用函数

array -- 声明一个数组 
count -- 计算数组中的单元数目或对象中的属性个数 
foreach -- 遍历数组 
list -- 遍历数组 
explode -- 将字符串转成数组 
implode -- 将数组转成一个新字符串 
array_merge -- 合并一个或多个数组 
is_array -- 检查是否是数组 
print_r -- 输出数组 
sort -- 数组排序 
array_keys -- 返回数组中所有的键名 
array_values -- 返回数组中所有的值 
key -- 从关联数组中取得键名

四、ArrayAccess(数组式访问)接口

4.1、功能介绍

提供像访问数组一样访问对象的能力的接口

4.2、接口摘要

ArrayAccess {
/* 方法 */
abstract public boolean offsetExists ( mixed $offset )
abstract public mixed offsetGet ( mixed $offset )
abstract public void offsetSet ( mixed $offset , mixed $value )
abstract public void offsetUnset ( mixed $offset )
}

4.3、例子

container = array(
            "one"   => 1,
            "two"   => 2,
            "three" => 3,
        );
    }
    public function offsetSet($offset, $value) {
        if (is_null($offset)) {
            $this->container[] = $value;
        } else {
            $this->container[$offset] = $value;
        }
    }
    public function offsetExists($offset) {
        return isset($this->container[$offset]);
    }
    public function offsetUnset($offset) {
        unset($this->container[$offset]);
    }
    public function offsetGet($offset) {
        return isset($this->container[$offset]) ? $this->container[$offset] : null;
    }
}

$obj = new obj;

var_dump(isset($obj["two"]));
var_dump($obj["two"]);
unset($obj["two"]);
var_dump(isset($obj["two"]));
$obj["two"] = "A value";
var_dump($obj["two"]);
$obj[] = 'Append 1';
$obj[] = 'Append 2';
$obj[] = 'Append 3';
print_r($obj);

五、数组有哪几种类型?

  • 数字索引数组

  • 关联数组

  • 根据数组构造还可以分一维数组、二维数组、多维数组。

六、用 PHP 实现一个双向队列

class DEQueue {
    //存储
    protected $_storage = array();
    
    //入头
    public function unshift($element)
    {
        return array_unshift($this->_storage, $element);
    }
    
    //入尾
    public function push($element)
    {
        return array_push($this->_storage, $element);
    }
    
    //出尾
    public function pop()
    {
        return array_pop($this->_storage);
    }
    
    //出头
    public function shift()
    {
        return array_shift($this->_storage);
    }
    
    //长度
    public function length()
    {
        return count($this->_storage);
    }
}

七、print_r、var_export、var_dump 的区别

$arr=[
    ["a"=>"aa","b"=>"bbb","c"=>"ccc"],
    ["a"=>"ddd","b"=>"eee","c"=>"fff"],
    ["a"=>"gg","b"=>"hh"]
];

八、PHP多种序列化/反序列化的方法(serialize和unserialize函数)

①、serialize和unserialize函数

 这两个是序列化和反序列化PHP中数据的常用函数。

$a = array('a' => 'Apple' ,'b' => 'banana' , 'c' => 'Coconut');
//序列化数组
$s = serialize($a);
echo $s;
//输出结果:a:3:{s:1:"a";s:5:"Apple";s:1:"b";s:6:"banana";s:1:"c";s:7:"Coconut";}
//反序列化
$o = unserialize($s);
print_r($o);
//输出结果 Array ( [a] => Apple [b] => banana [c] => Coconut )
//当数组值包含如双引号、单引号或冒号等字符时,它们被反序列化后,可能会出现问题。为了克服这个问题,一个巧妙的技巧是使用base64_encode和base64_decode。
$obj = array();
//序列化
$s = base64_encode(serialize($obj));
//反序列化
$original = unserialize(base64_decode($s));
//但是base64编码将增加字符串的长度。为了克服这个问题,可以和gzcompress一起使用。
//定义一个用来序列化对象的函数
function my_serialize( $obj )
{
   return base64_encode(gzcompress(serialize($obj)));
}
//反序列化
function my_unserialize($txt)
{
   return unserialize(gzuncompress(base64_decode($txt)));
}

②、json_encode 和 json_decode

使用JSON格式序列化和反序列化是一个不错的选择:

使用json_encode和json_decode格式输出要serialize和unserialize格式快得多。

JSON格式是可读的。

JSON格式比serialize返回数据结果小。

JSON格式是开放的、可移植的。其他语言也可以使用它。

$a = array('a' => 'Apple' ,'b' => 'banana' , 'c' => 'Coconut');
//序列化数组
$s = json_encode($a);
echo $s;
//输出结果:{"a":"Apple","b":"banana","c":"Coconut"}
//反序列化
$o = json_decode($s);

在上面的例子中,json_encode输出长度比上个例子中serialize输出长度显然要短。

③、var_export 和 eval

var_export 函数把变量作为一个字符串输出;eval把字符串当成PHP代码来执行,反序列化得到最初变量的内容。

$a = array('a' => 'Apple' ,'b' => 'banana' , 'c' => 'Coconut');
//序列化数组
$s = var_export($a , true);
echo $s;
//输出结果: array ( 'a' => 'Apple', 'b' => 'banana', 'c' => 'Coconut', )
//反序列化
eval('$my_var=' . $s . ';');
print_r($my_var);

④、wddx_serialize_value 和 wddx deserialize

wddx_serialize_value函数可以序列化数组变量,并以XML字符串形式输出。

$a = array('a' => 'Apple' ,'b' => 'banana' , 'c' => 'Coconut');
//序列化数组
$s = wddx_serialize_value($a);
echo $s;
//输出结果(查看输出字符串的源码):echo '

';
//反序列化
$o = wddx_deserialize($s);
print_r($o);
//输出结果:Array ( [a] => Apple [b] => banana 1 => Coconut )

可以看出,XML标签字符较多,导致这种格式的序列化还是占了很多空间。

九、PHP json_encode转换空数组为对象

①、问题描述:

php在给端提供接口,比如PC和安卓,ios等,如果返回json格式的数据,当返回数据的为数组,且key为字符串时,json化后将返回jsonObject,但是如果是空数组,有可能返回的就是jsonArray,数据结构不一致导致端解析json失败。

$arr = [
    'id' => 123.,
    'name' => 'andrew',
];
$jsonRet = json_encode($arr);
print_r($jsonRet);

输出:

{
  "id": 123,
  "name": "andrew"
}

但是如果是:

$arr = [];
$jsonRet = json_encode($arr);
print_r($jsonRet);

输出:

[
  
]

②、如何在数组为空时也是JsonObject呢?

方法一:

使用JSON_FORCE_OBJECT

$arr = [];
$jsonRet = json_encode($arr, JSON_FORCE_OBJECT);
print_r($jsonRet);

此法有一弊端,eg:

$arr = [
'jsonArray' => [
'21', '12', '13'
],
'jsonObject' => []
];
$jsonRet = json_encode($arr,JSON_FORCE_OBJECT);
print_r($jsonRet);

输出:

{
"jsonArray": {
"0": "21",
"1": "12",
"2": "13"
},
"jsonObject": {

}
}

原本jsonArray的也被jsonObject化了,局部的改变不能影响全局

方法二(推荐)

使用 ArrayObject

$arr = [
'jsonArray' => [
'21', '12', '13'
],
'jsonObject' => new \ArrayObject()
];
$jsonRet = json_encode($arr);
print_r($jsonRet);

输出:

{
"jsonArray": [
"21",
"12",
"13"
],
"jsonObject": {

}
}

打赏

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码打赏,你说多少就多少

打开微信扫一扫,即可进行扫码打赏哦

阅读 2404