括号匹配(栈)

日常编程中,我们都会用到编译器,但如果我们编写的代码在出现了问题,例如左右括号没有完全的匹配的时候,程序就无法通过运行,这个时候编译器就会报错,那么我们探究一下编译器是如何检查出这个错误的。
首先我们知道一个程序就像是一个字符串(忽略空格),我们的括号匹配问题就应在这个字符串中进行处理和查找。但是我们知道相邻的括号是一组,而不是最里面和最外面的随意匹配,因此在多个括号组中,往往最开始的括号是最后一个匹配的,这非常符合栈的先进后出原则,因此我们可以使用一个栈来保存这些括号。
在这里插入图片描述

这个时候我们的编译器挨个去扫描字符串,然后当匹配到左括号的时候,就将左括号放入栈中,然后当扫描到右括号的时候,将栈顶的括号进行匹配,然后将栈中的弹出,如果栈中已经为空了,那说明此时的右括号没有匹配到左括号。如果字符串依次扫描结束,栈中还剩余左括号没有匹配,那说明这个左括号无法匹配到右括号。如果匹配完成,刚刚好,说明程序没有括号匹配上的语法错误。
在这里插入图片描述
在这里插入图片描述

#include<iostream>
#pragma warning (disable:4996)
#define SEQSTACK_TRUE 1
#define SEQSTACK_FALSE 0

using namespace std;
//用数组去模拟栈的顺序储存
#define MAX_SIZE 1024

typedef struct SEQSTACK
{
	void* data[MAX_SIZE];
	int size;

}Seqstack;
//初始化栈
Seqstack* Init_Seqstack();
//入栈操作
void Push_Seqstack(Seqstack* stack, void* data);
//返回栈顶元素
void* Top_Seqstack(Seqstack* stack);
//出栈
void Pop_Seqstack(Seqstack* stack);
//判断是否为空
int IsEmpty(Seqstack* stack);
//返回栈中元素的个数
int Size_SeqStack(Seqstack* stack);
//销毁
void FreeSeqStack(Seqstack* stack);
//清空
void Clear_SeqStack(Seqstack* stack);

//初始化栈
Seqstack* Init_Seqstack()
{
	Seqstack* stack = new Seqstack;
	stack->data[MAX_SIZE] = { NULL };
	stack->size = 0;
	return stack;
}
//入栈操作
void Push_Seqstack(Seqstack* stack, void* data)
{
	if (stack->size == MAX_SIZE || stack == NULL || data == NULL)
		return;
	stack->data[stack->size] = data;
	stack->size++;
}
//返回栈顶元素
void* Top_Seqstack(Seqstack* stack)
{
	if (stack == NULL || stack->size == 0)
		return NULL;
	return stack->data[stack->size - 1];
}
//出栈
void Pop_Seqstack(Seqstack* stack)
{
	if (stack->size == 0 || stack == NULL)
		return;
	stack->size--;
}
//判断是否为空
int IsEmpty(Seqstack* stack)
{
	if (stack->size == 0)
		return SEQSTACK_TRUE;
	return SEQSTACK_FALSE;
}
//返回栈中元素的个数
int Size_SeqStack(Seqstack* stack)
{
	return stack->size;
}
//销毁
void FreeSeqStack(Seqstack* stack)
{
	delete stack;
}
//清空
void Clear_SeqStack(Seqstack* stack)
{
	if (stack == NULL)
		return;
	stack->size = 0;
}
typedef struct Mychar
{
	char* Paddress;//字符
	int index;//标识下位置
};
int IsLeft(char c)
{
	return c == '(';
}    
int IsRight(char c)
{
	return c == ')';
}
Mychar* CreatMychar(char* p,int index)
{
	Mychar* mychar = new Mychar;
	mychar->Paddress = p;
	mychar->index = index;
	return mychar;
}
void ShowError(char* str, int pos)
{
	cout << str << endl;
	for (int i = 0; i < pos; i++)
	{
		cout << " ";
	}
	cout << "A";
}
int main(void)
{
	char* str = (char*)"#incl(ude<stdio.h> int main(){int a[4][4]; int (*p)[4];return 0;}";
	char* p = str;
	int index = 0;
	//创建栈 
	Seqstack* stack = Init_Seqstack();
	//扫描字符串,如果碰到左括号直接入栈,如果碰到右括号,直接从栈顶弹出括号,
	// 判断是否左括号,如果是,匹配成功,如果不是,匹配失败
	while (*p != '\0')
	{
		//如果是左括号,直接进栈
		if (IsLeft(*p))
		{
			Push_Seqstack(stack, CreatMychar(p,index));
		}
		//如果是右括号,从栈顶弹出元素,判断是否左括号
		if (IsRight(*p))
		{
			if (Size_SeqStack(stack) > 0)
			{
				Mychar* mychar = (Mychar*)Top_Seqstack(stack);
				if (IsLeft(*mychar->Paddress))
					Pop_Seqstack(stack);
				delete mychar;
			}
			else
			{
				cout << "该处右括号没有匹配到左括号" << endl;
				ShowError(str, index);
				break;
			}
		}
		p++;
		index++;
	}
	while (Size_SeqStack(stack) > 0)
	{
		Mychar* mychar=(Mychar*)Top_Seqstack(stack);
		cout << "左括号没有匹配的右括号:" << endl;
		ShowError(str, mychar->index);
		Pop_Seqstack(stack);
		delete mychar;

	}

	

	return 0;
}

在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值