关于括号匹配的一个小问题,请教各位

Jing123qiang 2017-11-20 11:27:00



0001 void trim ( const char exp[], int& lo, int& hi ) { //删除exp[lo, hi]不含括号的最长前缀、后缀
0002 while ( ( lo <= hi ) && ( exp[lo] != '(' ) && ( exp[lo] != ')' ) ) lo++; //查找第一个和
0003 while ( ( lo <= hi ) && ( exp[hi] != '(' ) && ( exp[hi] != ')' ) ) hi--; //最后一个括号
0004 }
0005
0006 int divide ( const char exp[], int lo, int hi ) { //切分exp[lo, hi],使exp匹配仅当子表达式匹配
0007 int mi = lo; int crc = 1; //crc为[lo, mi]范围内左、右括号数目之差
0008 while ( ( 0 < crc ) && ( ++mi < hi ) ) //逐个检查各字符,直到左、右括号数目相等,或者越界
0009 { if ( exp[mi] == ')' ) crc--; if ( exp[mi] == '(' ) crc++; } //左、右括号分别计数
0010 return mi; //若mi <= hi,则为合法切分点;否则,意味着局部不可能匹配
0011 }
0012
0013 bool paren ( const char exp[], int lo, int hi ) { //检查表达式exp[lo, hi]是否括号匹配(递归版)
0014 trim ( exp, lo, hi ); if ( lo > hi ) return true; //清除不含括号的前缀、后缀
0015 if ( exp[lo] != '(' ) return false; //首字符非左括号,则必不匹配
0016 if ( exp[hi] != ')' ) return false; //末字符非右括号,则必不匹配
0017 int mi = divide ( exp, lo, hi ); //确定适当的切分点
0018 if ( mi > hi ) return false; //切分点不合法,意味着局部以至整体不匹配
0019 return paren ( exp, lo + 1, mi - 1 ) && paren ( exp, mi + 1, hi ); //分别检查左、右子表达式
0020 }

只鉴别小括号是否匹配。标红色的那一段我不太理解。我的疑惑是,什么时候mi>hi?
希望得到各位的帮助
...全文
143 1 打赏 收藏 转发到动态 举报
写回复
用AI写文章
1 条回复
切换为时间正序
请发表友善的回复…
发表回复
赵4老师 2017-11-22
  • 打赏
  • 举报
回复
仅供参考:
#include<stdio.h>
#include<malloc.h>
#include<string.h>
#define STACK_INIT_SIZE 10
#define STACK_GROW_SIZE 5
#define ELEMTYPE char
#define OK 1
#define ERROR 0
typedef struct { /*建立一个栈的首结点*/
    ELEMTYPE * base;
    ELEMTYPE * top;
    int stacksize;
} SpStack;
int InitStack(SpStack *s) { /*建立空的栈并返回首地址*/
    s->base=((ELEMTYPE*)malloc(STACK_INIT_SIZE*sizeof(ELEMTYPE)));
    if (!s->base) return ERROR;
    s->top=s->base;
    s->stacksize=STACK_INIT_SIZE;
    return OK;
}
int StackEmpty(SpStack *s) { /*判断栈是否为空*/
    if (s->top==s->base) return OK;
    else                 return ERROR;
}
int Push(SpStack *s,ELEMTYPE e) { /*往栈顶插入元素即进栈*/
    if (s->top-s->base>=s->stacksize) { /*判断是否栈满*/
        s->base=((ELEMTYPE*)realloc(s->base,(s->stacksize+STACK_GROW_SIZE)*sizeof(ELEMTYPE)));
        if (!s->base) return ERROR;
        s->stacksize+=STACK_GROW_SIZE;
        s->top=s->base+s->stacksize;
    }
    *s->top++=e;
    return OK;
}
int Pop(SpStack *s,ELEMTYPE *e) { /*让栈顶元素依次输出即出栈*/
    if (StackEmpty(s)) return ERROR;
    *e=*(--s->top);
    return OK;
}
int Comp(ELEMTYPE a,ELEMTYPE b) {
    if ((a=='('&&b!=')')
      ||(a=='['&&b!=']')
      ||(a=='{'&&b!='}')) {
        return ERROR;
    } else return OK;
}
int Count(SpStack *s) {
    ELEMTYPE e[STACK_INIT_SIZE*2];
    ELEMTYPE e1;
    int i;

    InitStack(s);
    fgets(e,STACK_INIT_SIZE*2,stdin);
    if ('\n'==e[strlen(e)-1]) e[strlen(e)-1]=0;
    printf("%s\n",e);
    for (i=0;e[i]!='\0';i++) {
        switch (e[i]) {
        case '(':
        case '[':
        case '{':
            Push(s,e[i]);
            break;
        case ')':
        case ']':
        case '}':
            if (StackEmpty(s)) {
                printf("%*s↖右括号多余\n",i+1,"");
                return(ERROR);
            } else Pop(s,&e1);
            if (!Comp(e1,e[i])) {
                printf("%*s↖左右匹配出错\n",i+1,"");
                return(ERROR);
            }
        }
    }
    if (!StackEmpty(s)) {
        printf("%*s↖左括号多余\n",i,"");
        return(ERROR);
    } else {
        printf("匹配正确\n");
        return(OK);
    }
}
void main() {
    SpStack s;
    Count(&s);
    free(s.base);
}
赵4老师 2017-11-21
  • 打赏
  • 举报
回复
代码功能归根结底不是别人帮自己看或讲解或注释出来的;而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒:再牛×的老师也无法代替学生自己领悟和上厕所! 单步调试和设断点调试(VS IDE中编译连接通过以后,按F10或F11键单步执行,按Shift+F11退出当前函数;在某行按F9设断点后按F5执行停在该断点处。)是程序员必须掌握的技能之一。 “给定一个小点的输入,完整单步跟踪(同时按Alt+7键查看Call Stack里面从上到下列出的对应从里层到外层的函数调用历史)一遍。”是理解递归函数工作原理的不二法门! 递归函数关注以下几个因素 ·退出条件 ·参数有哪些 ·返回值是什么 ·局部变量有哪些 ·全局变量有哪些 ·何时输出 ·会不会导致堆栈溢出
Larry_666 2017-11-21
  • 打赏
  • 举报
回复
多动动手,单步调试

64,637

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧