C語言利用棧的操作實現判斷字符串中的括號是否匹配(只考慮半角括號:( ) { } [ ])
題目均在sdibt acm oj上AC,參考《深入淺出數據結構和算法》教材,逐個複製即可運行,歡迎評論指正!
Description
輸入一串字符串,編寫算法判斷字符串中的括號是否匹配,如果匹配,輸出1,否則輸出0。
注: 只考慮半角括號:( ) { } [ ],不考慮全角括號:( ) 【 】
例如:{ab123[(3*6-(4+3)) {223}[999]hhh}
字符串中的括號匹配。
{323[ab]()(123}
字符串中的括號不匹配。
提示:利用棧實現。
Input
輸入可以包含各種括號、數字、字母等符號的字符串。
Output
括號匹配輸出1,否則輸出0。
Sample Input
sample 1:
{ab123[(3*6-(4+3)){223}[999]hhh}
sample 2:
{323
Description
輸入一串字符串,編寫算法判斷字符串中的括號是否匹配,如果匹配,輸出1,否則輸出0。
注: 只考慮半角括號:( ) { } [ ],不考慮全角括號:( ) 【 】
例如:{ab123[(3*6-(4+3)) {223}[999]hhh}
字符串中的括號匹配。
{323[ab]()(123}
字符串中的括號不匹配。
提示:利用棧實現。
Input
輸入可以包含各種括號、數字、字母等符號的字符串。
Output
括號匹配輸出1,否則輸出0。
Sample Input
sample 1:
{ab123[(3*6-(4+3)){223}[999]hhh}
sample 2:
{323[ab]()123}
Sample Output
sample1:
0
sample2:
1
ab]()123}
Sample Output
sample1:
0
sample2:
1
設計棧(順序棧)和相關頭文件以及宏定義如下:
#include <stdio.h>
#include <stdlib.h>
#define STACK_SIZE 30
typedef struct{
char *base;//棧底指針
char *top;//棧頂指針,始終指向棧頂位置,當top=base的時候標記棧空狀態
int size;//棧的當前長度
}seqStack;
操作集如下:分別是棧的初始化、入棧出棧、獲取棧頂元素
/**
* 創建一個stack
* @param s
* @return
*/
int InitStack(seqStack *s){
s->base = (char *)malloc(STACK_SIZE* sizeof(seqStack));
//省略是否空間滿的if判斷
s->top = s->base;
s->size = STACK_SIZE;
return 1;
}
/**
* 入棧
* @param s
* @param x
* @return
*/
int Push(seqStack *s,char x){
//省略stack滿,追加空間,本程序最多支持30長度的字符串判斷匹配,可以修改宏定義
*s->top = x;//修改內容
s->top++; //修改指針
return 1;
}
/**
* 出棧
* @param s
* @param x
* @return
*/
int Pop(seqStack *s,char *x){
if(s->top == s->base)return 0;//棧空判斷
else{
s->top--;
*x = *s->top;
return 1;
}
}
int GetTop(seqStack *s, char *x){
if(s->top==s->base)return 0;
else{
*x=*(s->top-1);
return 1;
}
}
核心函數:判斷匹配函數Match
以及主要遍歷字符串函數 BracketMatch(switch分支寫的是最騷的)👍
/**
* 判斷匹配
* @param ch1
* @param ch2
* @return
*/
int Match(char ch1,char ch2)
{
if(ch1=='{'&&ch2=='}'||ch1=='['&&ch2==']'||ch1=='('&&ch2==')')
return 1;
else return 0;
}
int BracketMatch(char *str){
seqStack s;
int i;
char ch;//接收彈出的字符
InitStack(&s);
for (i=0;str[i]!=0;i++) {
switch(str[i])
{
case '(':
case '[':
case '{':Push(&s,str[i]);
break;
case ')':
case ']':
case '}':GetTop(&s,&ch);
if (Match(ch,str[i]))
{
Pop(&s,&ch);//匹配的字符出棧
}else{
return 0;
}
}
//printf("%c\n",str[i]);
}
return 1;
}
主函數:面函數:)
int main()
{
char ch[30];//創建字符數組
char* ptr = ch;
scanf("%s",ch);
printf("%d\n",BracketMatch(ptr));
return 0;
}
總結
參數傳遞採用的都是實參傳地址,形參用指針接,在函數內對指針進行操作的方式。在需要返回函數狀態的同時返回對其操作的元素(如char或者int等)可以設置函數返回值爲int(函數狀態)傳參的時候傳入對其操作的元素的地址,在函數形參地方使用指針接收,在函數內修改。
初始化的時候,分配空間s->base = (char *)malloc(STACK_SIZE* sizeof(seqStack))
-> 設置棧頂指針指向棧底指針的操作s->top = s->base ->設置棧的最大長度s->size = STACK_SIZE
對出棧操作和取棧頂元素操作都要加入 if(s->top == s->base) return 0判斷棧空的操作
每一次判斷的完成,都需要棧頂元素pop出來,不然無法對下一個元素操作。