下面我们将探讨栈在 PHP 中的实现与应用.
理解栈
栈是线性数据结构,遵循着后进先出的原则.这意味着栈只有一个端口可以提供添加和移除元素.栈的插入操作叫做进栈,删除操作叫做出栈.
- 入栈
- 出栈
- 弹出顶端元素
- 是否为空
下面用 PHP 用不同的方法来实现栈.首先先用 PHP 内建数组函数,然后用其他数据结构例如链表
使用 PHP 数组实现栈
interface IStack {
public function push(string $item);
public function pop();
public function top();
public function isEmpty();
}
class Stack implements IStack
{
private $limit;
private $stack;
public function __construct(int $limit = 20)
{
$this->limit = $limit;
$this->stack = [];
}
public function pop(): string
{
if ($this->isEmpty()) {
throw new UnderflowException('Stack is empty');
} else {
return array_pop($this->stack);
}
}
public function push(string $newItem)
{
if (count($this->stack) < $this->limit) {
array_push($this->stack, $newItem);
} else {
throw new OverflowException('Stack is full');
}
}
public function top(): string
{
return end($this->stack);
}
public function isEmpty(): bool
{
return empty($this->stack);
}
}
使用链表实现栈
use LinkedList;
class BookList implements Stack
{
private $stack;
public function __construct()
{
$this->stack = new LinkedList();
}
public function pop(): string
{
if ($this->isEmpty()) {
throw new UnderflowException('Stack is empty');
} else {
$lastItem = $this->top();
$this->stack->deleteLast();
return $lastItem;
}
}
public function push(string $newItem)
{
$this->stack->insert($newItem);
}
public function top(): string
{
return $this->stack->getNthNode($this->stack->getSize())->data;
}
public function isEmpty(): bool
{
return $this->stack->getSize() == 0;
}
}
使用 SplStack 类 实现栈
如果我们不想自己实现栈,可以使用已经存在 SPL 来实现.SplStack通过 SplDoublyLinkedList 来实现.
$books = new SplStack();
$books->push("Introduction to PHP7");
$books->push("Mastering JavaScript");
$books->push("MySQL Workbench tutorial");
echo $books->pop() . "\n";
echo $books->top() . "\n";”
栈的使用
栈在实际应用的开发中有很多使用,如:浏览器历时等.下面看一下实际的问题
括号嵌套匹配
当我们在解决数学计算表达式的问题,首先应该考虑括号的正确嵌套.如:
8*(9-2) + {(4*5) / (2*2)}
5*8*9 / (3*2))
[{(2*7) + (15-3)]
上面的表达式只有一个是正确的,为了检测是正确,我们可以使用栈来实现.下面是实现的算法:
function expressionChecker(string $expression): bool
{
$valid = TRUE;
$stack = new SplStack();
for ($i = 0; $i < strlen($expression); $i++) {
$char = substr($expression, $i, 1);
switch ($char) {
case '(':
case '{':
case '[':
$stack->push($char);
break;
case ')':
case '}':
case ']':
if ($stack->isEmpty()) {
$valid = FALSE;
} else {
$last = $stack->pop();
if (($char == ")" && $last != "(")
|| ($char == "}" && $last != "{")
|| ($char == "]" && $last != "[")
) {
$valid = FALSE;
}
}
break;
}
if (!$valid)
break;
}
if (!$stack->isEmpty()) {
$valid = FALSE;
}
return $valid;
}
$expressions = [];
$expressions[] = "8 * (9 -2) + { (4 * 5) / ( 2 * 2) }";
$expressions[] = "5 * 8 * 9 / ( 3 * 2 ) )";
$expressions[] = "[{ (2 * 7) + ( 15 - 3) ]";
foreach ($expressions as $expression) {
$valid = expressionChecker($expression);
if ($valid) {
echo "Expression is valid \n";
echo "<br>";
} else {
echo "Expression is not valid \n";
echo "<br>";
}
}
返回
Expression is valid
Expression is not valid
Expression is not valid