3.2栈的应用-括号匹配

括号匹配代码
#include<stdio.h>
#include<malloc.h>
#include<stdbool.h>
#define STACK_MAX_SIZE 10

/**
  * Linear stack of integers. The key is data. stack 栈 
  */
  typedef struct CharStack {
	int top;
	
	int data[STACK_MAX_SIZE];//The maximum length is fixed. 
  } *CharStackPtr;
  
/**
  * Output the stack.
  */
 void outputStack(CharStackPtr paraStack) {
 	int i;
 	for(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 element.
  */
  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;
	}//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 pushPopTest() {
	printf("---- PushPopTest begins. ----\r\n");
	char ch;
  	
	//Initialize.
	CharStackPtr tempStack = charStackInit();//初始化
	printf("After initialization, the stack is: ");
	outputStack(tempStack);
	
	//Push.
	for(ch = 'a'; ch < 'm'; ch++) {
		printf("Pushing %c.\r\n", ch);
		push(tempStack, ch);
		outputStack(tempStack);
	}//Of for i
	
	//Pop.
	int i;
	for(i = 0; i < 3; i++) {
		ch = pop(tempStack);
		printf("Pop %c.\r\n", ch);
		outputStack(tempStack);
	}//Of for i
	
	printf("---- pushPopTest ends. ----\r\n");
  }//Of pushPopTest
  
/**
  * Is the bracket matching?
  * @param paraString The given expression.
  * @return Match or not. 
  */
  bool bracketMatching(char* paraString, int paraLength) {
	// Step 1. Initialize the stack through pushing a '#' at the bottom.
	CharStackPtr tempStack = charStackInit();
	push(tempStack, '#');//将#压入栈底,用于判断栈中是否有数据
	char tempChar, tempPopedChar;
	
	// Step 2. Process the string.
	int i;
	for(i = 0; i < paraLength; i++) {
		tempChar = paraString[i];
		
		switch(tempChar) {
			case '(':
			case '[':
			case '{':
				push(tempStack, tempChar);
				break;
			case ')':
				tempPopedChar = pop(tempStack);
				if(tempPopedChar != '(') {
					return false;
				}//Of if
				break;
			case ']':
				tempPopedChar = pop(tempStack);
				if(tempPopedChar != '[') {
					return false;
				}//Of if
				break;
			case '}':
				tempPopedChar = pop(tempStack);
				if(tempPopedChar != '{') {
					return false;
				}//Of if
				break;
			default:
				//Do nothing.
				break;
		}//Of switch
	}//Of for i
	
	tempPopedChar = pop(tempStack);
	if(tempPopedChar != '#') {
		return true;
	}//Of if
	
	return true;
  }//Of bracketMatching
  
/**
  * Unit test.
  */ 
  void bracketMatchingTest() {
	char* tempExpression = "[2 + (1 - 3)] * 4";
	bool tempMatch = bracketMatching(tempExpression, 17);
	printf("In the expression '%s' bracket matching? %d\r\n", tempExpression, tempMatch);
	
	tempExpression = "( ) )";
	tempMatch = bracketMatching(tempExpression, 6);
	printf("In the expression '%s' bracket matching? %d\r\n", tempExpression, tempMatch);
	
	tempExpression = "()()(())";
	tempMatch = bracketMatching(tempExpression, 8);
	printf("In the expression '%s' bracket matching? %d\r\n", tempExpression, tempMatch);
	
	tempExpression = "({}[])";
	tempMatch = bracketMatching(tempExpression, 6);
	printf("In the expression '%s' bracket matching? %d\r\n", tempExpression, tempMatch);
	
	tempExpression = ")(";
	tempMatch = bracketMatching(tempExpression, 2);
	printf("In the expression '%s' bracket matching? %d\r\n", tempExpression, tempMatch);
  }
/**
  * The entrance.
  */
 void main() {
// 	pushPopTest();
 	bracketMatchingTest();
 }//Of main
运行结果

在这里插入图片描述

检查push和pop的代码
#include<stdio.h>
#include<malloc.h>

#define STACK_MAX_SIZE 10

/**
  * Linear stack of integers. The key is data. stack 栈 
  */
  typedef struct CharStack {
	int top;
	
	int data[STACK_MAX_SIZE];//The maximum length is fixed. 
  } *CharStackPtr;
  
/**
  * Output the stack.
  */
 void outputStack(CharStackPtr paraStack) {
 	int i;
 	for(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 element.
  */
  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;
	}//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 pushPopTest() {
	printf("---- PushPopTest begins. ----\r\n");
	char ch;
  	
	//Initialize.
	CharStackPtr tempStack = charStackInit();//初始化
	printf("After initialization, the stack is: ");
	outputStack(tempStack);
	
	//Push.
	for(ch = 'a'; ch < 'm'; ch++) {
		printf("Pushing %c.\r\n", ch);
		push(tempStack, ch);
		outputStack(tempStack);
	}//Of for i
	
	//Pop.
	int i;
	for(i = 0; i < 3; i++) {
		ch = pop(tempStack);
		printf("Pop %c.\r\n", ch);
		outputStack(tempStack);
	}//Of for i
	
	printf("---- pushPopTest ends. ----\r\n");
  }//Of pushPopTest
/**
  * The entrance.
  */
 void main() {
 	pushPopTest();
// 	bracketMatchingTest();
 }//Of main
运行结果

在这里插入图片描述

代码分析

括号是否匹配核心代码:

bool bracketMatching(char* paraString, int paraLength) {
	// Step 1. Initialize the stack through pushing a '#' at the bottom.
	CharStackPtr tempStack = charStackInit();
	push(tempStack, '#');//将#压入栈底,用于判断栈中是否有数据
	char tempChar, tempPopedChar;
	
	// Step 2. Process the string.
	int i;
	for(i = 0; i < paraLength; i++) {
		tempChar = paraString[i];
		
		switch(tempChar) {
			case '(':
			case '[':
			case '{':
				push(tempStack, tempChar);
				break;
			case ')':
				tempPopedChar = pop(tempStack);
				if(tempPopedChar != '(') {
					return false;
				}//Of if
				break;
			case ']':
				tempPopedChar = pop(tempStack);
				if(tempPopedChar != '[') {
					return false;
				}//Of if
				break;
			case '}':
				tempPopedChar = pop(tempStack);
				if(tempPopedChar != '{') {
					return false;
				}//Of if
				break;
			default:
				//Do nothing.
				break;
		}//Of switch
	}//Of for i

分析:首先采用bool函数,只返回true或者false,然后关键是使用switch判断语句求"()“”[]“”{}“是否匹配。将这些括号按顺序入栈,如果遇到”)“”]“”}"判断之前的一个是否为与之匹配的括号,如果不是则直接返回false,跳出switch语句,后面的都不需要再查看了,但如果正确则一直执行,直到代码结束,则完全匹配,返回true
栈可以直接添加元素,不用从头遍历,添加速度快,且由于栈只允许栈顶进出元素,栈的顺序存储结构很方便,但需要先确定数组存储空间的大小

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值