几乎所有的编译器都具有检测括号是否匹配的能力
如何实现编译器中的符号成对检测?
#include <stdio.h> int main() { int a[4][4]; int (*p)[4]; p = a[0]; return 0;
算法思路
(1)从第一个字符开始扫描
(2)当遇见普通字符时忽略,当遇见左符号时压入栈中
(3)当遇见右符号时从栈中弹出栈顶符号,并进行匹配匹配成功:继续读入下一个字符
匹配失败:立即停止,并报错
结束:
成功: 所有字符扫描完毕,且栈为空
失败:匹配失败或所有字符扫描完毕但栈非空
当需要检测成对出现但又互不相邻的事物时
可以使用栈“后进先出”的特性,栈非常适合于需要“就近匹配”的场合
#include "linkstack.h"
#define MAX 1024
/*判断字符是不是左括号,是左括号返回1,不是则返回0*/
int isLeft(char ch)
{
if (ch == '(' || ch == '{' || ch == '[' ||
ch == '\"' || ch == '\'' || ch == '<')
{
return 1;
}
return 0;
}
/*判断字符是不是右括号,是右括号返回1,不是则返回0*/
int isRight(char ch)
{
if (ch == ')' || ch == '}' || ch == ']' ||
ch == '\"' || ch == '\'' || ch == '>')
{
return 1;
}
return 0;
}
/*对两个字符进行匹配,匹配成功返回1,失败则返回0*/
int isMatch(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;
default:
break;
}
return ret;
}
/*对目标字符串进行扫描处理*/
void scanner(char * src)
{
LinkStack * stack = NULL;
stack = LinkStack_Create();//创建栈
char tmp = '\0';//用来存放栈顶元素的临时变量
if (stack == NULL)//合法性
{
printf("create fail!\n");
return;
}
/*一直扫描到字符串尾部*/
while (*src != '\0')
{
/*如果是左括号则入栈*/
if (isLeft(*src))
{
LinkStack_Push(stack, (LinkStackNode*)src);
}
/*如果是右括号则进行匹配*/
if (isRight(*src))
{
/*弹出栈顶元素*/
tmp = *(char*)LinkStack_Pop(stack);
/*如果弹出的栈顶元素和刚刚扫描到的右括号不匹配则匹配失败--停止扫描
如果栈里面没有左括号--栈为空(表示先扫描到右括号)则匹配失败--停止扫描*/
if (!isMatch(tmp,*src) || (tmp == NULL))
{
printf("can not match!\n");
break;
}
}
/*指向目标字符串字符的指针移动*/
src++;
}
/*如果栈为空且已经扫描完目标字符串则表示匹配成功(语法正确)*/
if (*src == '\0' && LinkStack_Size(stack) == 0)
{
printf("OK!\n");
}
else if (LinkStack_Size(stack) > 0)//虽然扫描完目标字符串,
//但栈里面有剩余的元素表示匹配失败
//表示字符串里面只有左括号没有右括号
{
printf("can not match!\n");
}
LinkStack_Destroy(stack);//销毁栈(回收内存)
}
int main()
{
char code[MAX] = "abcd(){}[}";
scanner(code);
system("pause");
return 0;
}