題目
編寫一個算法,檢查一個程序中的花括號、方括號和圓括號是否配對,若全部配對,則返回1, 否則返回0.對於程序中出現的對單 引號或雙引號內的字符不進行括號配對檢查。 39爲單引號的ASCII值,34 爲雙引號的ASCII值,單引號和雙引號如果出現則必成對出現。
假設stack是已經定義的順序棧結構體。可以直接調用的元素進棧/出棧、取棧頂元素、判斷棧空的函數定義如下:
- void push(stack &S, char ch) ;
- void pop(stack &S, char &ch) ;
- void getTop(stack S,char &ch) ;
- int isEmpty(stack S) ;//若棧S空,則返回1,否則返回0
分析
在算法中,掃描程序中的每一個字符,當掃描到每個左花括號、左方括號、左圓括號時,令其進棧:當掃描到右花括號、右方括號、右圓括號時,則檢查棧頂是否爲相應的左括號,若是則做退棧處理,若不是則表明出現了語法錯誤,返回0.當掃描到程序文件結尾後,若棧爲空,則表明沒有發現括號配對錯誤,返回1:否則表明棧中還有未配對的括號,返回0。另外,對於一對單引號或雙引號內的字符不進行括號配對檢查。
代碼
核心代碼:
/* 對字符數組str中所有的字符進行括號配對 */
int bracketsCheck(char str[],int n) {
SqStack st;// 定義一個棧
int i=0;// 定義一個變量,記錄數組下標
while(i<n) {
if(str[i]==39) {// 判斷字符是否是單引號
i++;// 跳過第一個單引號
while(str[i]!=39) {
i++;// 跳過單引號中的內容
}
i++;// 跳過最後一個單引號
} else if(str[i]==34) {// 判斷字符是否是雙引號
i++;// 跳過第一個雙引號
while(str[i]!=34) {
i++;// 跳過雙引號中的內容
}
i++;// 跳過最後一個雙引號
} else {// 跳過單引號和雙引號後進行括號配對
if(str[i]=='('||str[i]=='['||str[i]=='{') {
push(st,str[i]);// 將符合上述情況的字符壓入棧中
} else if(str[i]==')') {// 判斷是否配對括號"()"
char x;
getTop(st,x);// 獲取棧頂元素
if(x=='(') {
pop(st,x);// 如果配對成功,則將該字符出棧
} else {
return 0;
}
} else if(str[i]==']') {// 判斷是否配對括號"[]"
char x;
getTop(st,x);
if(x=='[') {
pop(st,x);
} else {
return 0;
}
} else if(str[i]=='}') {// 判斷是否配對括號"{}"
char x;
getTop(st,x);
if(x=='{') {
pop(st,x);
} else {
return 0;
}
}
i++;
}
}
/* 判斷最後結果,如果爲空則全部配對正確,否則未配對成功 */
if(isEmpty(st)==1) {
return 1;// 配對成功返回1
} else {
return 0;// 配對失敗返回0
}
}
完整代碼:
#include <stdio.h>
#define maxSize 20
typedef struct {
char data[maxSize];// 存放棧中元素,maxSize是已經定義好的常量
int top;// 棧頂指針
} SqStack; // 順序棧類型定義
/* 初始化順序棧 */
/* &st指的是要操作的順序棧 */
void initStack(SqStack &st) {
st.top=-1; // 只需將棧頂指針設置爲-1,本棧中將top=-1規定爲棧空狀態
}
/* 判斷棧空 */
/* st指的是要進行判空的順序棧 */
int isEmpty(SqStack st) {
// 棧爲空的時候返回1,否則返回0
if(st.top==-1) { // 判空的條件是棧頂指針是否等於-1
return 1;
} else {
return 0;
}
}
/* 判斷棧滿 */
/* st指的是要進行判滿的順序棧 */
int isFull(SqStack st) {
// 如果棧頂指針等於maxSize-1那麼棧滿,否則棧空
if(st.top==maxSize-1) { // maxSize是棧中最大元素個數,已經定義
return 1;// 棧滿返回1
} else {
return 0;// 棧空返回0
}
}
/* 進棧 */
/* &st指的是要操作的棧;x指的是要進棧的數據 */
int push(SqStack &st,char x) {
/* 進棧首先要判斷棧是否棧滿,如果滿棧則不能進棧 */
if(isFull(st)==1) {
return 0;// 如果棧滿返回0,表示不能進棧
} else {
// 注意:++top和top++在這裏的作用是一樣的,都可以使用,如果是a=++top和a=top++,那麼兩個a的值是不一樣的,最後top的值還是一樣
++st.top;// 先移動指針,再進棧
st.data[st.top]=x;
return 1;// 進棧成功返回1
}
}
/* 出棧 */
/* &st指的是要操作的棧;&x指的是要出棧的數據 */
int pop(SqStack &st,char &x) {
/* 出棧之前要判斷棧是否爲空 */
if(isEmpty(st)==1) {// 1表示棧空,0表示非空
return 0;// 如果棧空,不能出棧,返回0
} else {
x=st.data[st.top];// 先取出元素,再出棧
--st.top;
return 1;// 出棧成功返回1
}
}
/* 得到棧頂元素 */
void getTop(SqStack st,char &x) {
if(isEmpty(st)==1) { // 如果棧空
x=' ';
} else {
x=st.data[st.top];
}
}
/* 打印棧,從左到右表示棧底到棧頂 */
/* stack表示要被打印的棧 */
void printStack(SqStack stack) {
printf("\n");
for(int i=0; i<=stack.top; i++) {// 注意:data[0]表示棧底元素,data[top]表示棧頂元素
printf("%c\t",stack.data[i]);// 打印棧中元素
}
printf("\n");
}
/* 對字符數組str中所有的字符進行括號配對 */
int bracketsCheck(char str[],int n) {
SqStack st;// 定義一個棧
int i=0;// 定義一個變量,記錄數組下標
while(i<n) {
if(str[i]==39) {// 判斷字符是否是單引號
i++;// 跳過第一個單引號
while(str[i]!=39) {
i++;// 跳過單引號中的內容
}
i++;// 跳過最後一個單引號
} else if(str[i]==34) {// 判斷字符是否是雙引號
i++;// 跳過第一個雙引號
while(str[i]!=34) {
i++;// 跳過雙引號中的內容
}
i++;// 跳過最後一個雙引號
} else {// 跳過單引號和雙引號後進行括號配對
if(str[i]=='('||str[i]=='['||str[i]=='{') {
push(st,str[i]);// 將符合上述情況的字符壓入棧中
} else if(str[i]==')') {// 判斷是否配對括號"()"
char x;
getTop(st,x);// 獲取棧頂元素
if(x=='(') {
pop(st,x);// 如果配對成功,則將該字符出棧
} else {
return 0;
}
} else if(str[i]==']') {// 判斷是否配對括號"[]"
char x;
getTop(st,x);
if(x=='[') {
pop(st,x);
} else {
return 0;
}
} else if(str[i]=='}') {// 判斷是否配對括號"{}"
char x;
getTop(st,x);
if(x=='{') {
pop(st,x);
} else {
return 0;
}
}
i++;
}
}
/* 判斷最後結果,如果爲空則全部配對正確,否則未配對成功 */
if(isEmpty(st)==1) {
return 1;// 配對成功返回1
} else {
return 0;// 配對失敗返回0
}
}
int main() {
SqStack st;
char str[]="(('[){}''[()}])'\")[}\"([)";
int n=24;
int r=bracketsCheck(str,n);
printf("括號配對結果(1表示成功,0表示失敗):%d",r);
return 0;
}
運行結果: