括号匹配问题
Posted w&y
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了括号匹配问题相关的知识,希望对你有一定的参考价值。
问题:假设一个算术表达式中可以包含三种括号:圆括号"(" 和
")",方括号"["和"]"和花括号"{"和"}",且这三种括号可按任意的
次序嵌套使用(如:…[…{…}…[…]…]…[…]…(…)…)。编写判别给定表达
式中所含括号是否正确配对出现的算法(已知表达式已存入数据元素
为字符的顺序表中)。
思路:
例如,考虑下列括号序列:
[ ( [ ] [ ] ) ]
1 2 3 4 5 6 7 8
当计算机接受了第一个括号后,它期待着与其匹配的第八个括号的出现,然而等来的却是第二个括号,此时第一个括号“[”只能暂时靠边,而迫切等待与第二个括号相匹配的、第七个括号“)”的出现,类似地,因等来的是第三个括号“[”,其期待匹配的程度较第二个括号更急迫,则第二个括号也只能靠边,让位于第三个括号,显然第二个括号的期待急迫性高于第一个括号;在接受了第四个括号之后,第三个括号的期待得到满足,消解之后,第二个括号的期待匹配就成为当前最急迫的任务了,……依此类推。
很显然,这样的一个处理过程和栈的特点非常吻合,因此,这个问题可以用栈来解决。
解决思路:
1.在算法中设置一个栈,每次读入一个括号;
2.若是右括号,则或者使置于栈顶的最急迫的期待得以消解,此时将栈顶的左括号弹出;或者是不合法的情况,此时将右括号压入;
3.若是左括号,则作为一个新的更急迫的期待压入栈中,自然使原有的在栈中的所有未消解的期待的急迫性都降低一级;
4.在算法的开始和结束时,栈应该为空。
代码:
1 <?php 2 /** 3 * 括号匹配问题 4 */ 5 class Stack 6 { 7 private $top = -1;//默认为-1,表示栈空 8 private $max_size = 100;//栈的最大容量(此处设置大一点,防止栈满无法入栈) 9 private $stack = array(); 10 11 /** 12 * 入栈 13 */ 14 private function push($val) 15 { 16 if ($this->top == $this->max_size-1) 17 { 18 return false;//栈满,不作处理 19 } 20 $this->top++; 21 $this->stack[$this->top] = $val; 22 } 23 24 /** 25 * 出栈 26 */ 27 private function pop() 28 { 29 if ($this->top == -1) 30 { 31 return false; 32 } 33 $value = $this->stack[$this->top]; 34 $this->top--; 35 return $value; 36 } 37 38 /** 39 * 取栈顶元素 40 */ 41 private function get_top() 42 { 43 if ($this->top == -1) 44 { 45 return false; 46 } 47 return $this->stack[$this->top]; 48 } 49 50 /** 51 * 判断栈是否为空 52 */ 53 private function is_empty() 54 { 55 if ($this->top == -1) 56 { 57 return true; 58 } else { 59 return false; 60 } 61 } 62 63 /** 64 * 括号匹配问题 65 */ 66 public function match($exp) 67 { 68 $len = strlen($exp);//省略字符串为空的校验 69 for($i=0; $i<$len; ++$i) 70 { 71 if($exp[$i] == ‘(‘ || $exp[$i] == ‘[‘ || $exp[$i] == ‘{‘)//若遇到左括号,直接入栈 72 { 73 $this->push($exp[$i]); 74 } else if($exp[$i] == ‘)‘) {//若遇到右圆括号,则尝试匹配栈顶括号 75 if($top = $this->get_top()) 76 { 77 if ($top == ‘(‘)//匹配成功,左括号出栈 78 { 79 $this->pop(); 80 } else {//匹配不成功,右括号入栈 81 $this->push($exp[$i]); 82 } 83 } else {//栈空,入栈 84 $this->push($exp[$i]); 85 } 86 } else if($exp[$i] == ‘}‘) {//若遇到右花括号,则尝试匹配栈顶括号 87 if($top = $this->get_top()) 88 { 89 if ($top == ‘{‘)//匹配成功,左括号出栈 90 { 91 $this->pop(); 92 } else {//匹配不成功,右括号入栈 93 $this->push($exp[$i]); 94 } 95 } else {//栈空,入栈 96 $this->push($exp[$i]); 97 } 98 } else if($exp[$i] == ‘]‘) {//若遇到右方括号,则尝试匹配栈顶括号 99 if($top = $this->get_top()) 100 { 101 if ($top == ‘[‘)//匹配成功,左括号出栈 102 { 103 $this->pop(); 104 } else {//匹配不成功,右括号入栈 105 $this->push($exp[$i]); 106 } 107 } else {//栈空,入栈 108 $this->push($exp[$i]); 109 } 110 } 111 } 112 //当所有括号匹配成功时,栈应为空 113 if($this->is_empty()) 114 { 115 return true; 116 } else { 117 return false; 118 } 119 } 120 } 121 122 $exp = "[()({[]})]"; 123 $s = new Stack(); 124 $ret = $s->match($exp); 125 if ($ret) 126 { 127 echo "success"; 128 } else { 129 echo "fail"; 130 }
以上是关于括号匹配问题的主要内容,如果未能解决你的问题,请参考以下文章