《数据结构和算法》之符号匹配性检测

来源:互联网 发布:大数据工程师加班吗 编辑:程序博客网 时间:2024/05/16 07:36

一,问题描述:

        在C语言中有一些符号是成对出现的,括号:(),【】,{},《》,<>;引号:“”,‘’;等都是成对出现,其在C语言中是无处不在的,几乎所有的编译器都具有语法检查的能力,其中有一项就是括号的匹配性检测,意思就是对应于左括号出现的时候就一定会有对应的右括号的匹配性检测。如何实现编译器中的符号成对检测呢?

二,问题分析:

        可能猛的看到这个题目都不知道要怎么做,但仔细分析之后可以发现可以从以下这个思路来进行解答:

        1,从第一个字符开始扫描,当遇见普通字符时忽略,当遇见左符号时压入栈中;

        2,当遇见右符号时就从栈中弹出栈顶符号进行匹配,如果匹配成功则继续读入下一个字符,如果匹配失败,可以立即停止并且报错;

        3,成功时:这个时候所有字符扫描完毕,且栈为空。

              失败时:匹配失败或者所有字符扫描完毕但栈非空。

       举例:

           

void f(int a[]){     int (*p)[5];     p= NULL;}

       首先,从v开始扫描,属于普通字符,一直扫描直到‘(’被扫描,此时将左符号压入栈中,接着继续扫描,又扫描到‘[’的时候遇到左符号,此时将该左符号压入栈中,继续扫描则遇到‘]’,此时‘[]’匹配成功,则这个两个符号从栈中弹出,再继续扫描,遇到‘)’,则刚好与之前的‘(’相匹配,此时“(”出栈,继续扫描,遇到‘{’,入栈,再接着‘(’又入栈,继续扫描直到‘)’此时匹配,出栈,继续扫描遇到‘[’入栈,继续遇到‘]’,又匹配成功,出栈;这样一直匹配到最后遇到‘}’,出栈,匹配成功,此时栈为空,最后扫描结束。

三,算法框架设计

       

int scanner(const char* code){LinkStack* stack = LinkStack_Create();//创建栈S; int ret = 0;int i = 0;while( code[i] != '\0'){    if(isLeft(code[i]))   //code[i]为左括号     {    LinkStack_Push(stack,(void*)(code + i));  //将code[i]出栈}if(isRight(code[i]))    //code[i]为右括号 {   char* c = (char*)LinkStack_Pop(stack);      //将code[i]入栈       if((c == NULL) || !match(*c,code[i]))    //如果c与code[i]不匹配    {        printf("%c does not match!\n",code[i]);     //此时报错 break;                                //停止循环    }}i++;}if((LinkStack_Size(stack)==0)&&(code[i]=='\0')){       printf("Succeed!\n");                //如果满足if里面的条件则匹配成功    ret = 1;}else{       printf("Invalid code!\n");         //如果不满足那些条件则匹配失败,报错    ret = 0;}LinkStack_Destroy(stack);                   //销毁栈,释放内存     return ret;}
            scanner算法的过程正如上述代码所示,首先要创建一个栈,按照上面二中的思路进行编写。判断左符号和右符号以及匹配函数均如下所示:

            左符号判断函数:

int isLeft(char c){int ret = 0; switch(c) {    case '<':case '(':case '[':case '{':case '\'':case '\"':ret = 1;break;default:ret = 0;break;  }  return ret;}
            右符号判断函数:    

int isRight(char c){int ret = 0; switch(c) {    case '>':case ')':case ']':case '}':case '\'':case '\"':ret = 1;break;default:ret = 0;break;  }  return ret;}
               匹配函数:

int match(char left, char right){int ret = 0;switch(left){    case '<':ret = (right == '>');break;case '(':ret = (right == ')');break;case '[':ret = (right == ']');break;case '{':ret = (right == '}');break;case '\'':ret = (right == '\'');break;case '\"':    ret = (right == '\"');break;default:ret = 0;break;}}
四,总的测试代码

            

#include <stdio.h>#include <stdlib.h>#include "LinkStack.h"/* run this program using the console pauser or add your own getch, system("pause") or input loop */int isLeft(char c){int ret = 0; switch(c) {    case '<':case '(':case '[':case '{':case '\'':case '\"':ret = 1;break;default:ret = 0;break;  }  return ret;}int isRight(char c){int ret = 0; switch(c) {    case '>':case ')':case ']':case '}':case '\'':case '\"':ret = 1;break;default:ret = 0;break;  }  return ret;}int match(char left, char right){int ret = 0;switch(left){    case '<':ret = (right == '>');break;case '(':ret = (right == ')');break;case '[':ret = (right == ']');break;case '{':ret = (right == '}');break;case '\'':ret = (right == '\'');break;case '\"':    ret = (right == '\"');break;default:ret = 0;break;}}int scanner(const char* code){LinkStack* stack = LinkStack_Create();//创建栈S; int ret = 0;int i = 0;while( code[i] != '\0'){    if(isLeft(code[i]))   //code[i]为左括号     {    LinkStack_Push(stack,(void*)(code + i));  //将code[i]出栈}if(isRight(code[i]))    //code[i]为右括号 {   char* c = (char*)LinkStack_Pop(stack);      //将code[i]入栈       if((c == NULL) || !match(*c,code[i]))    //如果c与code[i]不匹配    {        printf("%c does not match!\n",code[i]);     //此时报错 break;                                //停止循环    }}i++;}if((LinkStack_Size(stack)==0)&&(code[i]=='\0')){       printf("Succeed!\n");                //如果满足if里面的条件则匹配成功    ret = 1;}else{       printf("Invalid code!\n");         //如果不满足那些条件则匹配失败,报错    ret = 0;}LinkStack_Destroy(stack);                   //销毁栈,释放内存     return ret;}int main(int argc, char *argv[]){const char* code = "void fint a[]) {int (*p)[5]; p = NULL;}";scanner(code);return 0;}
              在输入"void fint a[]) {int (*p)[5]; p = NULL;}"字符串的时候会出现图1结果

                                             

                                                                                                                             图1  结果不成功的现象截图 

               在输入"void f(int a[]) {int (*p)[5]; p = NULL;}"的时候会出现图2结果:

                                               

                                                                                                                             图2 结果成功的截图

                                                   

0 0