【七】栈的应用实例(一)

来源:互联网 发布:snow软件下载 编辑:程序博客网 时间:2024/05/18 08:50

1、提出问题

在C语言中有一些符号是成对匹配出现的
 括号: ( ), [ ], { }, <>
 引号: ‘ ‘, “ “
检查它们是否成对出现是所有编译器实现的基本功能,可用于基本的语法检查,这个问题就可通过栈来实现!

2、算法实现思路

  • 从第一个字符开始扫描
  • 当遇见普通字符时忽略,当遇见左符号时压入栈中
  • 当遇见右符号时从栈中弹出栈顶符号
  • 进行匹配
    • 匹配成功:继续读入下一个字符
    • 匹配失败:立即停止 ,并报错
  • 结束:
    • 成功:所有字符扫描完毕,且栈为空
    • 失败:匹配失败或所有字符扫描完毕但栈非空

3、算法具体实现

/*  扫描字符串中的符号是否匹配*/bool scanner(const char *code){  bool ret = false;  LinkStack *stack = LinkStack_Create();  int i = 0;  while(code[i] != '\0')  {    //获取栈顶元素    char *top = (char*)LinkStack_Top(stack);    //判断是否是左值    if(isLeft(code[i]))    {      //如果栈顶为空,则直接将左值入栈      //否则,检查栈顶是否为双引号和单引号      if(top != NULL)      {        //如果不是双引号和单引号,则继续将左值入栈        //否则,不入栈,因为双引号和单引号中的任何字符都为普通字符        if(*top != '\'' && *top != '\"')        {          LinkStack_Push(stack,(LinkStackNode*)(code + i));          //入栈后执行下一次循环          i++;          continue;        }      }      else      {        LinkStack_Push(stack,(LinkStackNode*)(code + i));      }    }//如果栈顶元素是双引号和单引号,直到code[i]也为双引号和单引号,才执行下面的isRight判断,//否则全部跳过    if(top != NULL)    {      if((*top == '\'' && code[i] != '\'' ) || (*top == '\"' && code[i] != '\"'))      {        i++;        continue;      }    }    //如果遇到右值,便将栈顶弹出,与该右值进行匹配,匹配不成功,则代码有语法错误    if(isRight(code[i]))    {      char *c = (char*)LinkStack_Pop(stack);      if(c == NULL || !isMatch(*c,code[i]))      {        printf("%c does not match!\n", code[i]);        ret = false;        break;      }    }    i++;  }  //所有字符检查完成后,如果栈中还有剩余,则代码有问题,否则,成功!  //判断code[i] == '\0'的原因是:如果还没扫描完所有字符,那么即使栈为空,也是失败的  if( (LinkStack_Size(stack) == 0) && (code[i] == '\0'))  {    printf("Succeed!\n");    ret = true;  }  else  {    printf("Invalid Code!\n");    ret = false;  }  LinkStack_Destroy(stack);  return ret;}

5、小结

  • 当需要检测成对出现但又互不相邻的事物时,可以使用栈“后进先出”的特性
  • 栈非常适合于需要“就近匹配”的场合

6、完整源码下载

文件名:scanner-1.0.tar.gz
链接: http://pan.baidu.com/s/1jGCb9XG 密码: ksec

文件名:scanner-1.1.tar.gz
链接: http://pan.baidu.com/s/1hqq1wgs 密码: 3gkt
说明:修复了由linklist.c中的List_Get()函数所引起的BUG,详情见链接!

编译步骤:
0.1 解压缩:tar -zxvf scanner-1.1.tar.gz
0.2 进入目录:./configure
0.3 生成Seqlist:make
0.4 运行程序:./Scanner

0 0
原创粉丝点击