括号匹配问题(栈的应用)–c语言实现
问题概述:
给你一串字符,不超过50个字符,可能包括括号、数字、字母、标点符号、空格,你的任务是检查这一串字符中的( ) ,[ ],{ }是否匹配。
检测括号是否成对出现“”:
这种就是匹配的
这种就不是匹配的
思路:
每出现一个左括号,就入栈(压栈)。
每出现一个右括号,就抵消(出栈操作)一个左括号。
不匹配情况:
(1)遇到一个右括号,栈内弹出的左括号与之不匹配,例如 此时的右括号是 ] 而栈内的左括号是 {
(2)匹配到最后一个括号。栈内已经空了,说明此时多出来了括号
(3)处理完所有括号,栈内非空
代码实现
(1)定义结构体
我们要先定义一个结构体,这个结构体中有一个数组用于存储元素,还有一个栈顶标记位top。因为栈是后进先出的。我们只需要一个栈顶标记位就可以对这个栈进行进栈出栈判空等的操作。
typedef struct CharStack {
int top;
int data[STACK_MAX_SIZE]; //The maximum length is fixed.
} *CharStackPtr;
(2)初始化栈
数组的下标是从0开始的,刚开始我们并没有存元素,所以让top==-1。当存入元素的时候,让top+1,然后在它标记的位置存储元素即可。
CharStackPtr charStackInit() {
CharStackPtr resultPtr = (CharStackPtr) malloc(sizeof(struct CharStack));
resultPtr->top = -1;
return resultPtr;
}
(3)入栈
void push(CharStackPtr paraStackPtr, int paraValue) {
if (paraStackPtr->top >= STACK_MAX_SIZE - 1) {
printf("Cannot push element: stack full.\r\n");
return;
}
paraStackPtr->top ++;
paraStackPtr->data[paraStackPtr->top] = paraValue;
}
(4)出栈
char pop(CharStackPtr paraStackPtr) {
if (paraStackPtr->top < 0) {
printf("Cannot pop element: stack empty.\r\n");
return '\0';
}
paraStackPtr->top--;
return paraStackPtr->data[paraStackPtr->top + 1];
}
(5)测试,压栈遍历
void pushPopTest() {
printf("---- pushPopTest begins. ----\r\n");
char ch;
CharStackPtr tempStack = charStackInit();
printf("After initialization, the stack is: ");
outputStack(tempStack);
for (ch = 'a'; ch < 'm'; ch ++) {
printf("Pushing %c.\r\n", ch);
push(tempStack, ch);
outputStack(tempStack);
}
for (int i = 0; i < 3; i ++) {
ch = pop(tempStack);
printf("Pop %c.\r\n", ch);
outputStack(tempStack);
}
printf("---- pushPopTest ends. ----\r\n");
}
完整代码
#include <stdio.h>
#include <malloc.h>
#define STACK_MAX_SIZE 10
typedef struct CharStack {
int top;
int data[STACK_MAX_SIZE]; //The maximum length is fixed.
} *CharStackPtr;
//遍历栈
void outputStack(CharStackPtr paraStack) {
for (int i = 0; i <= paraStack->top; i ++) {
printf("%c ", paraStack->data[i]);
}
printf("\r\n");
}
//初始化栈
CharStackPtr charStackInit() {
CharStackPtr resultPtr = (CharStackPtr) malloc(sizeof(struct CharStack));
resultPtr->top = -1;
return resultPtr;
}
//新元素入栈
void push(CharStackPtr paraStackPtr, int paraValue) {
if (paraStackPtr->top >= STACK_MAX_SIZE - 1) {
printf("Cannot push element: stack full.\r\n");
return;
}
paraStackPtr->top ++;
paraStackPtr->data[paraStackPtr->top] = paraValue;
}
//栈顶元素出栈
char pop(CharStackPtr paraStackPtr) {
if (paraStackPtr->top < 0) {
printf("Cannot pop element: stack empty.\r\n");
return '\0';
}
paraStackPtr->top--;
return paraStackPtr->data[paraStackPtr->top + 1];
}
//测试,压栈遍历
void pushPopTest() {
printf("---- pushPopTest begins. ----\r\n");
char ch;
CharStackPtr tempStack = charStackInit();
printf("After initialization, the stack is: ");
outputStack(tempStack);
for (ch = 'a'; ch < 'm'; ch ++) {
printf("Pushing %c.\r\n", ch);
push(tempStack, ch);
outputStack(tempStack);
}
for (int i = 0; i < 3; i ++) {
ch = pop(tempStack);
printf("Pop %c.\r\n", ch);
outputStack(tempStack);
}
printf("---- pushPopTest ends. ----\r\n");
}
//匹配算法
bool bracketMatching(char* paraString, int paraLength) {
CharStackPtr tempStack = charStackInit();//初始化栈
push(tempStack, '#');//栈底元素赋值,方便后序判断
char tempChar, tempPopedChar;
for (int 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;
}
break;
case ']':
tempPopedChar = pop(tempStack);
if (tempPopedChar != '[') {
return false;
}
break;
case '}':
tempPopedChar = pop(tempStack);
if (tempPopedChar != '{') {
return false;
}
break;//扫描到右括号,若栈顶元素与之不匹配,则括号匹配失败,返回false
default:
break;
}
}
//退出循环后,判断栈内是否还有左括号
tempPopedChar = pop(tempStack);
if (tempPopedChar != '#') {
return false;
}
return true;
}
//测试用例
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);
}
int main() {
bracketMatchingTest();
}
运行结果
Is the expression '[2 + (1 - 3)] * 4' bracket matching? 1
Is the expression '( ) )' bracket matching? 0
Is the expression '()()(())' bracket matching? 1
Is the expression '({}[])' bracket matching? 1
Is the expression ')(' bracket matching? 0
进程已结束,退出代码0
其中“0”表示匹配失败,“1”表示匹配成功。