栈(Stack):是只允许在一端进行插入或删除的线性表。首先栈是一种线性表,但限定这种线性表只能在某一端进行插入和删除操作。
今天通过括号匹配的代码应用来实现出栈,入栈的学习
代码如下:
#include<stdio.h>
#include<malloc.h>
#define STACK_MAX_SIZE 10
typedef struct CharStack {
int top;
int data[STACK_MAX_SIZE];
}*CharStackPtr;
//output the stack
void outputstack(CharStackPtr paraStack){
for (int i = 0; i <= paraStack->top; i++){
printf("%c ", paraStack->data[i]);
}//off for i.
printf("\r\n");
}//off outputstack.
/*初始化一个空栈,这个函数没有错误检查
*使用paraStackPtr指向并用于改变这个栈.
*使用数组paraValues存储所有元素.
*/
CharStackPtr charStackInit(){
CharStackPtr resultPtr = (CharStackPtr)malloc(sizeof(struct CharStack));
resultPtr->top = -1;
return resultPtr;
}//off charStackInit.
//此函数push用于将元素放入栈中并表示为paraValue.
void push(CharStackPtr paraStackPtr, int paraValue){
//1.检查空间
if(paraStackPtr->top >= STACK_MAX_SIZE - 1){
printf("此栈已满,不能再放入元素\n");
return;
} //off if.
//2.更新栈顶
paraStackPtr->top++;
//3.放入元素.
paraStackPtr->data[paraStackPtr->top] = paraValue;
} //off push.
//此函数pop用于取出栈中元素,返回值是取出的元素.
char pop(CharStackPtr paraStackPtr){
//1.检查空间.
if(paraStackPtr->top < 0){
printf("此栈为空,不能取出元素\n");
return '\0';
} //off if.
//2.更新栈顶.
paraStackPtr->top--;
//3.取出元素.
return paraStackPtr->data[paraStackPtr->top+1];
}//off pop.
//此函数用于push和pop函数功能的测试.
void pushpopTest(){
printf("-----测试开始-----\r\n");
char ch;
//初始化.
CharStackPtr tempStack = charStackInit();
printf("初始化完成后的栈为: ");
outputstack(tempStack);
//放入.
for(ch = 'a'; ch < 'm'; ch++){
printf("放入: %c.\r\n", ch);
push(tempStack, ch);
outputstack(tempStack);
} //off for i.
//取出.
for (int i = 0; i<3; i++){
ch = pop(tempStack);
printf("取出: %c.\r\n", ch);
outputstack(tempStack);
} //off for i.
printf("-----测试结束-----\r\n");
} //off pushpopTest.
//括号匹配测试
bool bracketMatching(char *paraString, int paraLength){
//1.初始化栈,将一个'#'放在栈底.
CharStackPtr tempStack = charStackInit();
push(tempStack, '#');
char tempChar, tempPopedChar;
//2.进行匹配.
for(int i = 0; i < paraLength; i++){
tempChar = paraString[i];
switch (tempChar){
case '(':
case '[':
case '{':
push(tempStack, tempChar);
break;//若遇到'(','[','{'则将其放入栈中.
//若遇到')',']','}'则将上方程序放入的元素赋值给tempPopedChar进行匹配.
case ')':
tempPopedChar = pop(tempStack);
if(tempPopedChar != '('){
return false;
}//off if.
break;
case ']':
tempPopedChar = pop(tempStack);
if(tempPopedChar != '['){
return false;
}//off if
break;
case '}':
tempPopedChar = pop(tempStack);
if(tempPopedChar != '{'){
return false;
}//off if.
break;
//若都不是则直接跳出.
default:
break;
}//off switch.
} //off for i.
tempPopedChar = pop(tempStack);
if(tempPopedChar != '#'){
return true;
}//off if.
return true;
}//off Matching.
//匹配函数测试.
void bracketMatchingTest(){
char* tempExpression = "[2+(1-3)]*4";
bool tempMatch = bracketMatching(tempExpression, 17);
printf("这个式子'%s'中的括号互相匹配吗? %d\r\n", tempExpression, tempMatch);
tempExpression = "( ) )";
tempMatch = bracketMatching(tempExpression, 6);
printf("这个式子'%s'中的括号互相匹配吗? %d\r\n", tempExpression, tempMatch);
tempExpression = "()()(())";
tempMatch = bracketMatching(tempExpression, 8);
printf("这个式子'%s'中的括号互相匹配吗? %d\r\n", tempExpression, tempMatch);
tempExpression = "({}[])";
tempMatch = bracketMatching(tempExpression, 6);
printf("这个式子'%s'中的括号互相匹配吗? %d\r\n", tempExpression, tempMatch);
tempExpression = ")(";
tempMatch = bracketMatching(tempExpression, 2);
printf("这个式子'%s'中的括号互相匹配吗? %d\r\n", tempExpression, tempMatch);
/*tempExpression = "({}[])(((";
tempMatch = bracketMatching(tempExpression, 9);
printf("这个式子'%s'中的括号互相匹配吗? %d\r\n", tempExpression, tempMatch);*/
} //off test.
int main(){
pushpopTest();
bracketMatchingTest();
}
运行结果如下:
代码思路:
每出现一个左括号( (或[或{ ),就入栈(压栈)。
每出现一个右括号( )或]或} ),就消除一个左括号(出栈)。