C语言利用栈的操作实现判断字符串中的括号是否匹配(只考虑半角括号:( ) { } [ ])
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出来,不然无法对下一个元素操作。