版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u014183456/article/details/80259641
如何实现编译器中的符号成对检测?
解决方案
算法思路
从第一个字符开始扫描
当遇见普通字符时忽略,当遇见左符号时压入栈
当遇见右符号时从栈中弹出栈顶符号
进行匹配
• 匹配成功:继续读入下一个字符
• 匹配失败:立即停止,并报错
结束:
• 成功: 所有字符扫描完毕,且栈为空
• 失败:匹配失败或所有字符扫描完毕但栈非空
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;
}
return ret;
}
int scanner(const char* code)
{
LinkStack* stack = LinkStack_Creat();
int ret = 0;
int i=0;
while(code[i] != '\0')
{
if(isLeft(code[i]))
{
LinkStack_Push(stack,(void*)code+i);
}
if(isRight(code[i]))
{
char*c = (char*)LinkStack_Pop(stack);
if((c==NULL) || (!match(*c,code[i])))
{
printf("%c dose not match!\n",code[i]);
ret = 0;
break;
}
}
i++;
}
if((LinkStack_Size(stack)==0)&&(code[i]=='\0'))
{
printf("Succeed!\n");
ret=1;
}
else
{
printf("Invalid code!\n");
ret = 0;
}
Linklist_Destory(stack);
return ret;
}
int main()
{
const char* code = "#include <stdio.h> int main() { int a[5][5]; int (*p)[4]; p = a[0]; printf(\"%d\\n\", &p[3][3] - &a[3][3]); return 0; }";
scanner(code);
return 0;
}
小结当需要检测成对出现但又互不相邻的事物时
可以使用栈 “ 后进先出 ” 的特性
栈非常适合于需要 “ 就近匹配 ” 的场合