3.2 括号匹配

文章介绍了如何使用栈数据结构来实现编辑器中的语法错误检查功能,特别是括号匹配。通过读入括号并利用栈的特性,可以有效地处理括号的嵌套和匹配问题。文章提供了具体的栈操作代码示例,并通过测试用例展示了匹配过程。
摘要由CSDN通过智能技术生成

一.问题引入

我们使用的编辑器中,有这样一种功能,就是检查语法的错误,比如有无分号,前面有左括号,检查后面是否有后括号,并将对应的括号做标记,我们今天就是探讨计算机是如何将这个功能实现的

二.思路分析

我们要对括号进行匹配,就需要先读入这串括号,我们首先考虑用数组的形式,发现读入是简单了,但要怎么匹配呢,特别是当括号有嵌套的情况,链表就更不可靠了,访问其中的数,还需要遍历,于是,栈这种受限的顺序表就出现了。

三.图解流程

在此之前,我们要先建立一个栈,以及其中的入栈和出栈等流程

这里直接使用了闵帆老师的代码(摘自数据结构 C 代码 3.1: 栈)

#include <stdio.h>
#include <malloc.h>

#define STACK_MAX_SIZE 10

/**
 * Linear stack of integers. The key is data
 */
typedef struct CharStack {
    int top;

    int data[STACK_MAX_SIZE]; //The maximum length is fixed.
} *CharStackPtr;

/**
 * Output the stack
 */
void outputStack(CharStackPtr paraStack) {
    for (int i = 0; i <= paraStack->top; i ++) {
        printf("%c ", paraStack->data[i]);
    }// Of for i
    printf("\r\n");
}// Of outputStack

/**
 * Initialize an empty char stack. No error checking for this function
 * @param paraStackPtr The pointer to the stack. It must be a pointer to change the stack
 * @param paraValues An int array storing all elements
 */
CharStackPtr charStackInit() {
	CharStackPtr resultPtr = (CharStackPtr)malloc(sizeof(struct CharStack));
	resultPtr->top = -1;

	return resultPtr;
}//Of charStackInit

/**
 * Push an element to the stack
 * @param paraValue The value to be pushed
 */
void push(CharStackPtr paraStackPtr, int paraValue) {
    // Step 1. Space check
    if (paraStackPtr->top >= STACK_MAX_SIZE - 1) {
        printf("Cannot push element: stack full\r\n");
        return;
    }//Of if

    // Step 2. Update the top
	paraStackPtr->top ++;

	// Step 3. Push element
    paraStackPtr->data[paraStackPtr->top] = paraValue;
}// Of push

/**
 * Pop an element from the stack
 * @return The popped value
 */
char pop(CharStackPtr paraStackPtr) {
    // Step 1. Space check
    if (paraStackPtr->top < 0) {
        printf("Cannot pop element: stack empty\r\n");
        return '\0';
    }//Of if

    // Step 2. Update the top
	paraStackPtr->top --;

	// Step 3. Push element
    return paraStackPtr->data[paraStackPtr->top + 1];
}// Of pop

/**
 * Test the push function
 */

当读入括号的时候,我们就要将还未成功匹配的括号压入栈中,如果有更加急迫的括号,就将这个更急迫的括号压入,直到有与之匹配的括号读入,此时再将该括号弹出。

图解如下

以( { } [ ] 为例

 代码如下

void bracketMatchingTest() {
	char* tempExpression = "[2 + (1 - 3)] * 4";
	bool tempMatch = bracketMatching(tempExpression, 17);
	printf("Is the expression '%s' bracket matching? %d \r\n", tempExpression, tempMatch);


	tempExpression = "( )  )";
	tempMatch = bracketMatching(tempExpression, 6);
	printf("Is the expression '%s' bracket matching? %d \r\n", tempExpression, tempMatch);

	tempExpression = "()()(())";
	tempMatch = bracketMatching(tempExpression, 8);
	printf("Is the expression '%s' bracket matching? %d \r\n", tempExpression, tempMatch);

	tempExpression = "({}[])";
	tempMatch = bracketMatching(tempExpression, 6);
	printf("Is the expression '%s' bracket matching? %d \r\n", tempExpression, tempMatch);


	tempExpression = ")(";
	tempMatch = bracketMatching(tempExpression, 2);
	printf("Is the expression '%s' bracket matching? %d \r\n", tempExpression, tempMatch);
}// Of bracketMatchingTest

输出结果如下

  0代表匹配不合法,1代表匹配合法。

四.收获

栈的编写和使用,让我体会到它的神奇之处,明明是操作受限的顺序表,但是却在解决实际问题上有着不一样的效果,它的强大之处在于能够简单对程序的执行顺序进行排序,因为它在被创建时就有着这样的功效。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值