栈的应用-括号的就近匹配

栈的应用-括号的就近匹配

代码块中,编译器通常会帮我们做符号等一些语法检查,提示在哪些地方语法错了,其中符号的就近匹配是用栈做的;
思路和代码如下:

//就近匹配是对栈的应用,程序中对括号的“就近匹配”用到的就是栈的思想
//1.从第一个字符开始扫描;2.当遇见普通字符的时候忽略;3.当遇见左符号的时候压栈;4.当遇见右符号时从栈顶弹出符号,并进行匹配
// 匹配成功:继续读入下一个字符
// 匹配失败:立即停止并报错
//结束:
// 成功:所有字符扫描完毕,且栈为空
// 失败:匹配失败或所有字符扫描完毕,栈不为空;
//需要说明的的是,压栈和出栈的一些api函数已经在上一篇文章中给出;
#include<iostream>
using namespace std;
#include"LinkStack.h"
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 == '\"');
	}
	return ret;
}

int scanner(const char* code)
{
	LinkStack* stack = LinkStack_Create();
	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]))//如果c为空或者左右不匹配,打印"does not match",并直接退出
			{
				cout << code[i] << "does not match" << endl;
				ret = 0;
				break;
			}
		}
		i++;
	}
	if ((LinkStack_Size(stack) == 0) && (code[i] == '\0'))//如果栈为空且所有字符都已经扫描完毕,打印"succeed"之后退出程序
	{
		cout << "succeed!" << endl;
		ret = 1;
	}
	else
	{
		cout << "invalid code" << endl;
		ret = 0;
	}
	return ret;
}
int  main()
{
	const char* code = "#include<stdio.h> int main() {int a[4][4];int(*p)[4];p=a[0];return 0;";
	scanner(code);
	return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值