1. 程式人生 > >括號匹配問題

括號匹配問題

nbsp 字符 match color dbf 防止 lose src false

問題:假設一個算術表達式中可以包含三種括號:圓括號"(" 和
")",方括號"["和"]"和花括號"{"和"}",且這三種括號可按任意的
次序嵌套使用(如:…[…{…}…[…]…]…[…]…(…)…)。編寫判別給定表達
式中所含括號是否正確配對出現的算法(已知表達式已存入數據元素
為字符的順序表中)。

思路:

例如,考慮下列括號序列:

  [ ( [ ] [ ] ) ]

  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 }
View Code

括號匹配問題