目标

给定一个只包括 ‘(‘,’)’,'{‘,’}’,'[‘,’]’ 的字符串,是否其有效。

有效的定义:

1.左括号必须用相同类型的右括号闭合。

2.左括号必须以正确的顺序闭合。

3.每个右括号都有一个对应的相同类型的左括号。

思路

使用栈来进行解决。

遇到左括号加入栈遇到右括号与栈顶第一个数据进行比较,如果相同则将该元素从栈顶消除,解决不匹配的情况就ok
不匹配的情况:
1.左方向的括号多余,可以用奇偶来判断吗,也可以用匹配法,匹配到最后栈内不为空,则不符合规则
2.匹配右括号时,与栈顶的括号类型不一致,不符合规则
3.右括号多余,字符串没有遍历完栈就为空了,不符合规则

public function isValid()
{
    $string = '()[]{}';
    if (strlen($string)%2!=0) return false;
    $stack = new SplStack();//继承双链表(SplDoublyLinkedList)来实现栈
    //可见栈和双链表的区别就是IteratorMode改变了而已,栈的IteratorMode只能为:
    //1.SplDoublyLinkedList::IT_MODE_LIFO | SplDoublyLinkedList::IT_MODE_KEEP (默认值,迭代后数据保存)
    //2.SplDoublyLinkedList::IT_MODE_LIFO | SplDoublyLinkedList::IT_MODE_DELETE (迭代后数据删除)
    for ($i=0;$i<strlen($string);$i++){
        if ($string[$i] == '('){
            $stack->push(')');//放到栈中,匹配的时候直接弹出来与元素作比较
        } elseif ($string[$i] == '{'){
            $stack->push('}');
        } elseif ($string[$i] == '['){
            $stack->push(']');
        }
        //1.遍历到这里时,元素应该是右边的括号之一
        //2.历匹配过程中,发现栈内没有要匹配的字符 return false
        //3.遍历匹配过程中,栈已为空,没有匹配的字符了,说明右括号没有找到对应的左括号 return false
        //$stack->top() 是查看最后一个入栈的数据,就是栈最上面的数据
        elseif ($stack->top() != $string[$i] || $stack->isEmpty() ){
            return  false;
        } else{
            $stack->pop();//如果在栈里能匹配到对应的左括号,就把栈里的这个数据消除
        }
    }
    return $stack->isEmpty();
}