堆棧所具備的後進先出的特性使得它在計算機領域中稱爲十分重要、也是應用十分普遍的數據結構之一。也就是說,實際應用中只要問題知足「後進先出」的原則,就可使用堆棧。好比說在編譯和運行的過程當中,就須要利用堆棧進行語法檢查(包括括號是否配對)和表達是求值。接下來咱們就來探討編譯過程當中計算機是如何對程序進行符號的匹配的。算法
問題描述
咱們都知道C語言的語法中,不少符號都是成對出現的,好比說「()」、「{ }」、「 【】」、「<>」。或者說是這樣的「 { < ( ) > } 」.
然而像這樣 「{ < } >」 、 " { { } "、 「{}} 」 等都是不符合語法的,都是錯誤的。基本上全部的編譯器都有檢查符號匹配性的功能,那麼他們是如何工做的呢?數據結構
問題分析
全部的程序均可以當作是字符串組成的,因此咱們能夠將他們分紅一個一個的字符,只須要將左右括號拿出來對比就好了,其餘的字符能夠不須要管。
例如一個字符串:" { while ( !Stack_Empty ( top ) ) }」框架
在這裏插入圖片描述函數
在這裏
1對應6
2對應5
3對應4
只有他們相互匹配才能說不出語法問題。那麼咱們該怎麼作呢?oop
建立一個棧,而後一個一個讀取字符串中全部的字符,遇到左括號將其壓入棧中,遇到右括號則將棧中的棧頂元素出棧並進行匹配,不然跳過讀取下一個字符。這個是一個大框架。
在這裏插入圖片描述在這裏插入圖片描述測試
那麼咱們就得判斷一個字符串中全部的符號是否匹配成功,有如下幾點:spa
若是第一個讀取的不是左括號則錯誤,直接返回並提示錯誤信息
若是讀取的右括號與棧頂的左括號不匹配,直接返回並提示錯誤信息
若是讀取完全部的字符串以後棧中還有多餘未匹配的左括號,直接返回並提示錯誤信息
這就是簡單的符號匹配的核心思想。code
算法框架blog
1 **************************************************** 2 判斷是否爲右括號 3 是:返回1 4 否:返回0 5 **************************************************** 6 int isRight(char ch) 7 { 8 int ret; 9 switch (ch) 10 { 11 case']': 12 case'}': 13 case')': 14 case'>': 15 ret = 1; 16 break; 17 default: 18 ret = 0; 19 break; 20 } 21 return ret; 22 }
1 *********************************************************************** 2 該函數用來判斷左右符號是否匹配 3 是:返回1 4 否:返回0 5 *********************************************************************** 6 int check(char Left, char Right) 7 { 8 int ret; 9 switch (Left) 10 { 11 case'<': 12 if (Right == '>')ret = 1; 13 break; 14 case'[': 15 if (Right == ']')ret = 1; 16 break; 17 case'{': 18 if (Right == '}')ret = 1; 19 break; 20 case'(':if (Right == ')')ret = 1; 21 break; 22 default: 23 ret = 0; 24 break; 25 26 } 27 return ret; 28 }
1 *********************************************************************** 2 該函數主要功能是讀取字符串,調用判斷左、右括號的函數,調用判斷是否匹配的函數 3 判斷是否棧中有剩餘左括號 4 若是無錯誤:返回1 5 不然:返回0 6 *********************************************************************** 7 int scanner(char cost[]) 8 { 9 int i = 0; 10 int ret = 0; 11 Stack top = Stack_Inten(); 12 char ch; 13 while (cost[i] != '\0') 14 { 15 16 if (isLeft(cost[i])) 17 top = Stack_Push(top, cost[i]); 18 if (isRight(cost[i])) 19 { 20 if (top == NULL) 21 return (ret = 0); 22 else 23 { 24 top = Stack_Pull(top, &ch); 25 if (!(ret = check(ch, cost[i]))) 26 return ret; 27 } 28 } 29 i++; 30 } 31 if (!Stack_Empty(top)) 32 { 33 Stack_Free(top); 34 return (ret = 0); 35 } 36 return (ret = 1); 37 }
總的測試代碼(包含棧)圖片
頭文件「check.h」
1 #include<stdio.h> 2 #include <stdlib.h> 3 4 5 typedef struct Stack_operate 6 { 7 char ch; 8 struct Stack_operate* link; 9 }Sta, *Stack; 10 11 12 Stack Stack_Inten(); 13 int Stack_Empty(Stack); 14 int Stack_Len(Stack); 15 Stack Stack_Push(Stack , char ); 16 Stack Stack_Pull(Stack , char *); 17 int Stack_Free(Stack ); 18 int isLeft(char ); 19 int isRight(char ); 20 int check(char , char ); 21 int scanner(char cost[]); 22 void panduan(int );
函數定義
1 #include"check.h" 2 3 Stack Stack_Inten() 4 { 5 return NULL; 6 } 7 8 9 int Stack_Empty(Stack top) 10 { 11 return(top == NULL); 12 } 13 14 15 16 int Stack_Len(Stack top) 17 { 18 int i = 0; 19 while (top != NULL) 20 { 21 top = top->link; 22 i++; 23 } 24 return i; 25 } 26 27 28 Stack Stack_Push(Stack top, char ch) 29 { 30 Stack p; 31 p = (Stack)malloc(sizeof(Sta)); 32 p->ch = ch; 33 p->link = top; 34 top = p; 35 return top; 36 } 37 38 39 40 Stack Stack_Pull(Stack top, char *p_ch) 41 { 42 Stack p; 43 *p_ch = top->ch; 44 p = top; 45 top = top->link; 46 free(p); 47 return top; 48 } 49 50 51 int Stack_Free(Stack top) 52 { 53 Stack p; 54 55 while (top != NULL) 56 { 57 p = top; 58 top = top->link; 59 free(p); 60 } 61 return 1; 62 } 63 64 65 int isLeft(char ch) 66 { 67 int ret; 68 switch (ch) 69 { 70 case '<': 71 case'(': 72 case'[': 73 case'{': 74 ret = 1; 75 break; 76 default: 77 ret = 0; 78 break; 79 } 80 return ret; 81 } 82 83 84 int isRight(char ch) 85 { 86 int ret; 87 switch (ch) 88 { 89 case']': 90 case'}': 91 case')': 92 case'>': 93 ret = 1; 94 break; 95 default: 96 ret = 0; 97 break; 98 } 99 return ret; 100 } 101 102 103 int check(char Left, char Right) 104 { 105 int ret; 106 switch (Left) 107 { 108 case'<': 109 if (Right == '>')ret = 1; 110 break; 111 case'[': 112 if (Right == ']')ret = 1; 113 break; 114 case'{': 115 if (Right == '}')ret = 1; 116 break; 117 case'(':if (Right == ')')ret = 1; 118 break; 119 default: 120 ret = 0; 121 break; 122 123 } 124 return ret; 125 } 126 127 128 int scanner(char cost[]) 129 { 130 int i = 0; 131 int ret = 0; 132 Stack top = Stack_Inten(); 133 char ch; 134 while (cost[i] != '\0') 135 { 136 137 if (isLeft(cost[i])) 138 top = Stack_Push(top, cost[i]); 139 if (isRight(cost[i])) 140 { 141 if (top == NULL) 142 return (ret = 0); 143 else 144 { 145 top = Stack_Pull(top, &ch); 146 if (!(ret = check(ch, cost[i]))) 147 return ret; 148 } 149 } 150 i++; 151 } 152 if (!Stack_Empty(top)) 153 { 154 Stack_Free(top); 155 return (ret = 0); 156 } 157 return (ret = 1); 158 } 159 160 void panduan(int i) 161 { 162 if (i = 1) 163 puts("Right!!!!!"); 164 else 165 puts("Error!!!!!"); 166 }
主函數等
1 int main(void) 2 { 3 int ret1 = 0; 4 int ret2 = 0; 5 char cost1[] = "the bookis< kkko,(slkj(sfd)sdg)agds{}>"; 6 char cost2[] = "lkdjfklajg<<jlksjfio>{}"; 7 8 ret1 = scanner(cost1); 9 ret2 = scanner(cost2); 10 11 puts("The first string is:"); 12 panduan(ret1); 13 puts("The second string is:"); 14 panduan(ret2); 15 16 return 0; 17 }
最終結果啦
這個算法到這裏就算是結束了。
嗝~
csdn中同步更新:codeloop