一、数组的查找
1.1、顺序查找
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、排序的两大类
2.2、冒泡排序法
①、基本思想
②、案例分析:从小到大排序
2.3、选择排序法
①、基本思想
②、案例分析:从小到大排序
2.4 、插入排序法
分三种:插入排序法、希尔排序法、二叉树排序法
①、基本思想
②、案例分析
function insertSort(&$arr)
{
//先默认下表为0这个数已经有序
for($i=1;$i=0 && $insertVal<$arr[$insertIndex]){
//把较大的数后移
$arr[$insertIndex+1] = $arr[$insertIndex];
$insertIndex--;
}
//插入(这时为$indexVal找到适当的位置了)
$arr[$insertIndex+1] = $insertVal;
}
}
2.5、快速排序法
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": {
}
}