栈(Stack):是只允许在一端进行插入或删除的线性表。首先栈是一种线性表,但限定这种线性表只能在某一端进行插入和删除操作。
通过括号匹配的代码应用来实现出栈,入栈的学习:
代码段:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <malloc.h>
#include <stdbool.h>
#define MAX_SIZE 10
typedef struct CharStack {
int top;
int data[MAX_SIZE];
} *CharStackPtr;
/*
* output the stack.
*/
void outputStack(CharStackPtr paraStack) {
for (int i = 0; i < paraStack->top; i++) {
printf("%c", paraStack->data[i]);
}
printf("\n");
}
/*
* Initialize an empty char stack,
* @param paraStackPtr The pointer to the stack.
* @param paraValues An int array storing all element.
*/
CharStackPtr charStackInit() {
CharStackPtr resultPtr = (CharStackPtr)malloc(sizeof(struct CharStack));
resultPtr->top = -1;//使得后续数组能从0开始
return resultPtr;
}
/*
* 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 >= MAX_SIZE - 1) {
printf("Cannnot push element: stack full.\r\n");
return;
}
//Step 2:Updata the top.
paraStackPtr->top++;
//Step 3:Push element.
paraStackPtr->data[paraStackPtr->top] = paraValue;
}
/*
* Pop an element from the stack.
* @return The popped value.
*/
char pop(CharStackPtr paraStackPtr) {
//Step 1:Space check.
if (paraStackPtr->top < 0) {//按道理来说此处top=-1时,栈就为空了,但谨慎起见,还是写成小于0就报错
printf("Cannot pop element: stack empty.\r\n");
return '\0';
}
//Step 2:Update the top.
paraStackPtr->top--;
//Step 3:Pop element.
return paraStackPtr->data[paraStackPtr->top + 1];
}
/*
* 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);
// Pop.
for (ch = 'a'; ch < 'm'; ch++) {
printf("Pushing %c.\r\n", ch);
push(tempStack, ch);
outputStack(tempStack);
}//Of for i
// Pop.
for (int 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 bracketMatching?
* @param paraString The given expresion.
* @return Match or not
*/
bool bracketMatching(char* paraString, int paraLength) {//char* 指向给出的字符串的首元素地址
//Step 1:Initialize the stack through pushing a '#' at the bottom.
CharStackPtr tempStack = charStackInit();
push(tempStack, '#');
char tempChar, tempPopedChar;
//Step 2:Process the string.
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;
}//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;
}
else {
return false;
}
}//of bracketMatching
/**
* Unit test.
*/
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, 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
int main() {
pushPopTest();
bracketMatchingTest();
return 0;
}
运行结果
---- pushPopTest begins. ----
After initialization, the stack is:
Pushing a.
a
Pushing b.
ab
Pushing c.
abc
Pushing d.
abcd
Pushing e.
abcde
Pushing f.
abcdef
Pushing g.
abcdefg
Pushing h.
abcdefgh
Pushing i.
abcdefghi
Pushing j.
abcdefghij
Pushing k.
Cannnot push element: stack full.
abcdefghij
Pushing l.
Cannnot push element: stack full.
abcdefghij
Pop j.
abcdefghi
Pop i.
abcdefgh
Pop h.
abcdefg
---- pushPopTest ends. ----
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
代码思路:
每出现一个左括号( (或[或{ ),就入栈(压栈)。
每出现一个右括号( )或]或} ),就消除一个左括号(出栈)。