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 
#include 
#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出来,不然无法对下一个元素操作。

你可能感兴趣的:(C语言,数据结构与算法)