棧的應用--括號匹配
一、實驗目的
本實驗是關於棧的應用,棧在各種高階語言編譯系統中應用十分廣泛,利用棧的“先進後出”的特點,分析C語言源程式程式碼中的的括號是否配對正確。
通過本實驗的學習,可以理解棧的基本操作的實現。
二、實驗內容
本實驗要求設計一個演算法,檢驗C源程式程式碼中的括號是否正確配對。對本演算法中的棧的儲存實現,我們採用的是順序儲存結構。要求能夠在某個C源程式上檔案上對所設計的演算法進行驗證。
三、程式分析
(1)int initStack(sqstack **s) 初始化一個棧
(2)int push(sqstack *s,char x) 入棧,棧滿時返回FALSE
(3)char pop(sqstack *s) 出棧,棧空時返回NULL
(4)int Empty(sqstack *s) 判斷棧是否為空,為空時返回TRUE
(5)int match(FILE *f) 對檔案指標f對指的檔案進行比較括號配對檢驗,從檔案中每讀入一個字元ch=fgetc(f),採用多路分支switch(ch)進行比較:
①若讀入的是“[”、“{”或“(”,則壓入棧中,
②若讀入的是“]”,則:若棧非空,則出棧,判斷出棧符號是否等於“[”,不相等,則返回FALSE。
③若讀入的是“}”,則:若棧非空,則出棧,判斷出棧符號是否等於“{”,不相等,則返回FALSE。
④若讀入的是“)”,則:若棧非空,則出棧,判斷出棧符號是否等於“(”,不相等,則返回FALSE。
⑤若是其它字元,則跳過。
檔案處理到結束時,如果棧為空,則配對檢驗正確,返回TRUE。
(6)主程式main()中定義了一個檔案指標,輸入一個已經存在的C源程式檔案。
四、程式原始碼
#include<stdio.h> #include<stdlib.h> #include<string.h> #define SIZE 10 typedef struct{ char sta[SIZE]; int top; }stack; //初始化棧 int initstack(stack *s) { memset(s->sta,0,sizeof(s->sta)); s->top=-1; return 0; } //壓棧 int push(stack *s,char x){ if((s->top)==SIZE-1) { printf("the stack is full\n"); return 1; } else{ (s->top)++; (s->sta)[s->top]=x; return 0; } } //出棧 char pop(stack *s){ char tmp; tmp=(s->sta)[s->top]; (s->top)--; return tmp; } //判空 int empty(stack *s){ if(s->top<0) { printf("the stack is empty\n"); return 1;} else return 0; } //呼叫 int main(){ stack s; int i; char m; char tmp; int flag=0; initstack(&s); for(i=0;i<SIZE;i++){ scanf("%c",&m); if(m=='(' || m=='[' || m=='{'){ push(&s,m); } else if(m==')' || m==']' || m=='}'){ if(m==')' ) { if(empty(&s)) printf("error\n"); else {tmp=pop(&s); if(tmp=='(' ) flag=1; else flag=0;} } if(m==']' ) { if(empty(&s)) printf("error\n"); else {tmp=pop(&s); if(tmp=='[' ) flag=1; else flag=0 ;} } if(m=='}' ) { if(empty(&s)) printf("error\n"); else {tmp=pop(&s); if(tmp=='{' ) flag=1; else flag=0;} } if(flag==1) printf("the no.%d brackets match successfully\n",(s.top)+2); else {printf("the no.%d brackets match unsuccessfully\n",(s.top)+2);break;} } else {i--;continue;} } return 0; }
# define MAXNUM 200 # define FALSE 0 # define TRUE 1 #include "stdio.h" #include "stdlib.h" #include "string.h" typedef struct { char stack[MAXNUM]; int top; } sqstack; /*定義棧結構*/ int initStack(sqstack **s) {/*初始化棧*/ if ((*s=(sqstack*)malloc(sizeof(sqstack)))==NULL) return FALSE; (*s)->top=-1; return TRUE; } int push(sqstack *s,char x) {/*將元素x插入到棧s中,作為s的新棧頂*/ if(s->top>=MAXNUM-1) return FALSE; /*棧滿*/ s->top++; s->stack[s->top]=x; return TRUE; } char pop(sqstack *s) {/*若棧s不為空,則刪除棧頂元素*/ char x; if(s->top<0) return NULL; /*棧空*/ x=s->stack[s->top]; s->top--; return x; } int Empty(sqstack *s) { /*棧空返回TRUE,否則返回FALSE*/ if(s->top<0) return TRUE; return FALSE;} int match(FILE *f) { char ch,ch1; sqstack *S; initStack(&S); while(!feof(f)) {ch=fgetc(f); switch(ch) {case '(': case '[': case '{':push(S,ch);printf("%c",ch);break; case ')': if (Empty(S)!=TRUE) {ch1=pop(S); printf("%c",ch); if (ch1=='(') break; else return FALSE; } else return FALSE; case ']': if (Empty(S)!=TRUE) {ch1=pop(S); printf("%c",ch); if (ch1=='[') break; else return FALSE; } else return FALSE; case '}':if (Empty(S)!=TRUE) {ch1=pop(S); printf("%c",ch); if (ch1=='{') break; else return FALSE; } else return FALSE; default:break; } } if (Empty(S)!=TRUE) return FALSE; return TRUE; } int main() {FILE *fp;char fn[20]; printf("請輸入檔名:"); scanf("%s",fn); if ((fp=fopen(fn,"r"))==NULL) {printf("不能開啟檔案\n"); exit(0);} else if (match(fp)==TRUE) printf("括號正確\n"); else printf("括號不正確\n"); fclose(fp);return 0; }
五、實驗結果
最後程式執行結果如下所示:
請輸入檔名: F:\exam.c<回車>
( ){ }括號正確