spl学习笔记
spl是干嘛的
spl是用于解决典型问题(standard problems)的一组接口与类的集合.
如果你想实现某个典型的数据结构,可以在spl类中查找是否有合适的。
只要简单的继承内置类,就可以实现这些数据结构。避免重复实现,可以
专注自己的业务逻辑。
数据结构
1.实现双向列表
SplDoublyLinkedList implements Iterator, ArrayAccess, Countable {}
example1:
FIFO and LIFO in SplDoublyLinkedList //先进先出
$list = new SplDoublyLinkedList();
$list->push('a');
$list->push('b');
$list->push('c');
$list->push('d');
echo "FIFO (first In First Out) : \n";
$list->setIteratorMode(SplDoublyLinkedList::IT_MODE_FIFO); //设置先进先出迭代模式
for ($list->rewind(); $list->valid(); $list->next()) {
echo $list->current(). "\n";
}
result:
//FIFO (First In First Out)
//a
//b
//c
//d
echo "LIFO (Last In First Out):
$list->setIteratorMode(SplDoublyLinkedList::IT_MODE_LIFO); //设置后进先出迭代模式
for ($list->rewind(); $list->valid(); $list->next()) {
echo $list->current() . "\n";
}
Result:
//LIFO (Last In First Out):
//d
//c
//b
//a
example2:
php doubly link list is an amazing data structure ,doubly means
you can traverse forward as well as backward, it can act as
a deque(double ended queue) if you want it to, here is how it works
$dlist = new SplDoublyLinkedList() //实例化
//从链表的末尾插入数据 push操作
$dlist->push('hiramariam);
$dlist->push('maaz');
$dlist->push('zafar');
//链表包含
/*
hiramariam
maaz
zafar
*/
//从链表的开头插入数据
$dlist->unshift(1);
$dlist->unshift(2);
$dlist->unshift(3);
//链表包含
/*
3
2
1
hiramariam
maaz
zafar
*/
//从链表底部删除 pop操作
$dlist->pop();
//链表包含
/*
3
2
1
hiramariam
maaz
*/
//shift操作
$dlist->shift()
/**
如果你想替换一个条目 如果索引的值超出限制 会抛出异常
**/
$dlist->add(3, 2.24);
/**
可以使用循环遍历链表
**/
//从前向后
/**
rewind() 指向链表的初始位置 取决于iterator模式 可能指向开头 也有可能指向末尾
valid() 是否可用
next() 指向下一个
**/
for ($dlist->rewind(); $dlist->valid(); $dlist->next()) {
echo $dlist->current() . "<br />";
}
//从后向前
$dlist->setIteratorMode(SplDoublyLinkedList::IT_MODE_LIFO);
for ($dlist->rewind(); $dlist->valid(); $dlist->next()) {
echo $dlsit->current() . "<br />";
}
//双链表的实现
SplDoublyLinkedList implements Iterator, ArrayAccess, Countable {
public __construct(void)
//实现的Iterator接口
public void rewind(void) //初始化链表指向的位置
public bool valid (void) //链表指向的地址是否有效
public mixed current(void) //当前元素
public mixed key(void) //当前元素的索引值
public void prev(void) //前一个
public void next(void) //下一个
public void add(mixed $index, mixed $newval) //添加
public mixed top (void) //返回顶部元素
public mixed bottom(void) //底部元素
//实现的Countable接口
public int count(void) //统计个数
public int getIteratorMode(void) //当前迭代模式 向前或向后
public void setIteratorMode(int $mode) //设置迭代模式
/**
mode 参数
There are two orthogonal(正交的) sets of modes that can be set: 两组设置互不影响
The direction of the iteration (either one or the other): 迭代的方向
SplDoublyLinkedList::IT_MODE_LIFO (Stack style) 栈的方式
SplDoublyLinkedList::IT_MODE_FIFO (Queue style) 队列的方式
The behavior of the iterator (either one or the other): 迭代的行为 下一次迭代的方向是否保留
SplDoublyLinkedList::IT_MODE_DELETE (Elements are deleted by the iterator)
SplDoublyLinkedList::IT_MODE_KEEP (Elements are traversed by the iterator)
默认的
The default mode is: SplDoublyLinkedList::IT_MODE_FIFO | SplDoublyLinkedList::IT_MODE_KEEP 方向设置为FIFO 下一次迭代还是这个模式
//位运算
/*
PHP 的 ini 设定 error_reporting 使用了按位的值,
提供了关闭某个位的真实例子。要显示除了提示级别
之外的所有错误,php.ini 中是这样用的:
E_ALL & ~E_NOTICE
具体运作方式是先取得 E_ALL 的值:
00000000000000000111011111111111
再取得 E_NOTICE 的值:
00000000000000000000000000001000
然后通过 ~ 将其取反:
11111111111111111111111111110111
最后再用按位与 AND(&)得到两个值中都设定了(为 1)的位:
00000000000000000111011111110111
另外一个方法是用按位异或 XOR(^)来取得只在
其中一个值中设定了的位:
E_ALL ^ E_NOTICE
error_reporting 也可用来演示怎样置位。只显示错误和可恢复
错误的方法是:
E_ERROR | E_RECOVERABLE_ERROR
也就是将 E_ERROR
00000000000000000000000000000001
和 E_RECOVERABLE_ERROR
00000000000000000001000000000000
用按位或 OR(|)运算符来取得在任何一个值中被置位的结果:
00000000000000000001000000000001
**/
public bool isEmpty(void) //链表是否为空
//实现的ArrayAccess接口
public bool offsetExists(mixed $index) //索引是否存在
public mixed offsetGet(mixed $index) //获取指定索引的元素
public void offsetSet(mixed $index, mixed $newval) //设置新索引的值
public void offsetUnset(mixed $index)
public mixed pop(void) //从末尾删除
public void push(mixed $value) //从末尾加入
public mixed shift (void) //从开头删除一个
public void unshift (mixed $value) //从开头加入
public void unserialize (string $serialized) //反序列化链表
public string serialiaze(void) //序列化
}
2.栈(Stack)是一种特殊的线性表,加为它只能在线性表的一端插入或删除元素(即进栈和出栈)
SplStack extends SplDoublyLinkedList implements Iterator, ArrayAccess, Countable {}
3.队列(SplQueue)就像我们生活中排队一样,和栈一样,它的特性是先进先出(FIFO).
SplQueue extends SplDoublyLinkedList implements Iterator, ArrayAccess, Countable {}
4.优先队列SplPriorityQueue是基于堆实现的。
SplPriorityQueue implements Iterator, Countable {}
5.堆(Heap)就是为了实现优先队列SplPriorityQueue而设计的一种数据结构,它是通过构造二叉堆(二叉树的一种)实现。
abstract SplHeap implements Iterator, Countable {}
6.阵列 处理巨大数量的固定长度数组时采用。
SplFixedArray implements Iterator, ArrayAccess, Countable {}
7.映射 用来存储一组对象的,特别是当你需要唯一标识对象的时候
SplObjectStorage implements Countable, Iterator, Serializable, ArrayAccess {}