zoukankan      html  css  js  c++  java
  • 栈的应用:表达式括号匹配检测(C)

    问题说明:

    假设数学表达式中允许包含两种括号:圆括号“()”和方括号“[]”,嵌套顺序任意。

    正确的嵌套模式:( [ ] ( ) )、[ ( [ ] [ ] ) ]

    正确的表达式例:(a+b)[c*(d-e)]

    错误的嵌套模式:[ ( ] )、( ( ) ]

    比如,在处理表达式(A)时

    (A)  4+(2+8)*[5/(9-7)]

    有以下步骤:

    (1)检测到第一个括号“(”;

    (2)检测到第二个括号“)”,说明子表达式 “4+(2+8)” 已完成匹配;

    (3)检测到第三个括号“[”;

    (4)检测到第四个括号“(”,与(3)中的括号不匹配,但由于同是左括号,可以继续匹配;

    (5)检测到第五个括号“)”,由括号的作用可知,后来的括号比先来的括号优先级高,因此与(4)中括号匹配;

    (6)检测到第六个括号“]”,由于原来优先级更高的括号已完成,因此与(3)中括号匹配。至此所有括号匹配完成。

    解决方案:

    可以看出,匹配成功的条件很简单:每一个检测到的括号与已检测到的优先级最高的括号都匹配。

    匹配失败的条件:

    (1)检测到与已检测到的优先级最高的括号不匹配的括号;

    (2)扫描完整个表达式,还是有已检测到的括号没有完成匹配;

    由于栈具有“先进后出”的特点,能很好地表现优先级这个性质,因此可以用栈来存储已经检测到的括号。

    以(A)为例:

    有以下步骤:

    (1)检测到第一个括号“(”,进栈;

    (2)检测到第二个括号“)”,进栈。子表达式 “4+(2+8)” 完成匹配,匹配的括号都出栈;

    (3)检测到第三个括号“[”,进栈;

    (4)检测到第四个括号“(”,进栈。与(3)中的括号不匹配,但由于同是左括号,可以继续匹配;

    (5)检测到第五个括号“)”,进栈。由括号的作用可知,后来的括号比先来的括号优先级高,因此与(4)中括号匹配,匹配的括号都出栈;

    (6)检测到第六个括号“]”,进栈。由于原来优先级更高的括号已完成,因此与(3)中括号匹配。匹配的括号都出栈,至此所有括号匹配完成。

    需要注意的是,第一个括号进栈时,没有比较对象,因此需要特别处理。

    判断函数 judge () 如下:

     1 Status judge(Stack *S)
     2 {
     3     //进行表达式的输入和判断 
     4     SElemType *p;
     5     char n;
     6     
     7     scanf("%c",&n);            //第一个括号的检测
     8     while(n!='(' && n!='[')        //忽略数字等其他符号,直到输入括号
     9     {
    10         if(n==')' || n==']' || n=='#')    return FALSE;    //若为')'或']',则表明不匹配。'#'用于结束输入
    11         scanf("%c",&n);    
    12     }
    13     
    14     if(n=='(' || n=='[')    Push(S,n);    //检测到左括号,进栈
    15     scanf("%c",&n);
    16     while(n!='#')    //'#'用于结束输入
    17     {    
    18         if(n=='(' || n==')' || n=='[' || n==']')
    19         {
    20             p=S->top;
    21             Push(S,n);
    22             if(*(p-1)=='(')        //与前一个括号比较
    23             {
    24                 if(*p==')')    
    25                 {
    26                     printf("%c
    ",Pop(S));
    27                     printf("%c
    ",Pop(S));
    28                 }
    29                 else if(*p==']')    return FALSE;
    30             }
    31             else if(*(p-1)=='[')
    32             {
    33                 if(*p==']')    
    34                 {
    35                     printf("%c
    ",Pop(S));
    36                     printf("%c
    ",Pop(S));
    37                 }
    38                 else if(*p==')')    return FALSE;
    39             }
    40         }
    41         scanf("%c",&n);
    42     }
    43     if(S->top==S->base)    return TRUE; //栈内没有元素时,说明匹配 
    44     else return FALSE;
    45 }

    源代码如下:

    #include <stdio.h>
    #include <stdlib.h>
    #define INIT_SIZE 10
    #define INCREMENT 5
    
    #define OVERFLOW -2
    #define FALSE 0 
    #define OK 1
    #define TRUE 1
    #define ERROR 0
    
    typedef char SElemType; 
    typedef int Status;
    typedef struct stack{
        SElemType *base;
        SElemType *top;
        int stacksize; 
    }Stack;
    
    Status InitStack(Stack *S)
    {
        //初始化栈 
        S->base=(SElemType *)malloc(INIT_SIZE*sizeof(SElemType));
        if(!S->base) exit(OVERFLOW);
        S->top=S->base;
        S->stacksize=INIT_SIZE;
        return OK;
    }
    
    Status Push(Stack *S,char e)
    {
        //入栈 
        if(S->top-S->base>=S->stacksize){    //栈满,重新分配内存 
            S->base=(SElemType *)realloc(S->base,(INIT_SIZE+INCREMENT)*sizeof(SElemType));
            if(!S->base) exit(OVERFLOW);
            S->top=S->base+S->stacksize;
            S->stacksize+=INCREMENT;
        }
        *S->top++=e;
        return OK;
    }
    
    char Pop(Stack *S)
    {
        //出栈 
        char e;
        
        if(S->top==S->base)    return ERROR;    //栈空,出错 
        e=*(--S->top);
        return e;
    }
    
    Status judge(Stack *S)
    {
        //进行表达式的输入和判断 
        SElemType *p;
        char n;
        
        scanf("%c",&n);            //第一个括号的检测
        while(n!='(' && n!='[')        //忽略数字等其他符号,直到输入括号
        {
            if(n==')' || n==']' || n=='#')    return FALSE;    //若为')'或']',则表明不匹配。'#'用于结束输入
            scanf("%c",&n);    
        }
        
        if(n=='(' || n=='[')    Push(S,n);    //检测到左括号,进栈
        scanf("%c",&n);
        while(n!='#')    //'#'用于结束输入
        {    
            if(n=='(' || n==')' || n=='[' || n==']')
            {
                p=S->top;
                Push(S,n);
                if(*(p-1)=='(')        //与前一个括号比较
                {
                    if(*p==')')    
                    {
                        printf("%c
    ",Pop(S));
                        printf("%c
    ",Pop(S));
                    }
                    else if(*p==']')    return FALSE;
                }
                else if(*(p-1)=='[')
                {
                    if(*p==']')    
                    {
                        printf("%c
    ",Pop(S));
                        printf("%c
    ",Pop(S));
                    }
                    else if(*p==')')    return FALSE;
                }
            }
            scanf("%c",&n);
        }
        if(S->top==S->base)    return TRUE; //栈内没有元素时,说明匹配 
        else return FALSE;
    }
    
    int main()
    {
        Stack Sta;
        Stack *S=&Sta;
        
        printf("INITIALIZING...
    ");
        if(InitStack(S)) printf("DONE!
    ");
    
        printf("enter an expression(stop by '#'):
    ");
        if(judge(S)==1)    printf("It's True!");
        else printf("It's False
    ");
        
        return 0;
    }
    source
  • 相关阅读:
    关于Maya Viewport 2.0 API 开发的介绍视频
    春节大假
    Some tips about the life cycle of Maya thread pool
    Can I compile and run Dx11Shader for Maya 2015 on my side?
    How to get current deformed vertex positions in MoBu?
    想加入全球首届的 欧特克云加速计划吗?
    三本毕业(非科班),四次阿里巴巴面试,终拿 offer(大厂面经)
    mac、window版编辑器 webstorm 2016... 永久破解方法。
    node 搭载本地代理,处理web本地开发跨域问题
    js 一维数组,转成嵌套数组
  • 原文地址:https://www.cnblogs.com/stargazer7/p/9823227.html
Copyright © 2011-2022 走看看