一、栈
1、定义
栈是限定于仅在表尾进行插入或删除操作的线性表,也称后进先出的线性表。表尾端称为栈顶,表头端称为栈底。没有任何元素的空表叫做空栈。
2、操作
栈的操作包括入栈和出栈:
3、代码及其运行结果
代码:
#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(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 poped 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 pushPopTest() {
printf("---- pushPopTest begins. ----\r\n");
// Initialize.
CharStackPtr tempStack = charStackInit();
printf("After initialization, the stack is: ");
outputStack(tempStack);
// Pop.
for (char 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
/**
The entrance.
*/
int main() {
pushPopTest();
return 0;
}// Of main
结果:
---- pushPopTest begins. ----
After initialization, the stack is:
Pushing a.
a
Pushing b.
a b
Pushing c.
a b c
Pushing d.
a b c d
Pushing e.
a b c d e
Pushing f.
a b c d e f
Pushing g.
a b c d e f g
Pushing h.
a b c d e f g h
Pushing i.
a b c d e f g h i
Pushing j.
a b c d e f g h i j
Pushing k.
Cannot push element: stack full.
a b c d e f g h i j
Pushing l.
Cannot push element: stack full.
a b c d e f g h i j
Pop j.
a b c d e f g h i
Pop i.
a b c d e f g h
Pop h.
a b c d e f g
---- pushPopTest ends. ----
二、栈的应用
1、括号匹配
代码:
#include <stdio.h>
#include <stdlib.h>
#define STACK_MAX_SIZE 10
typedef struct CharStack {
int top;
int data[STACK_MAX_SIZE];
} *CharStackPtr;
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
CharStackPtr charStackInit() {
CharStackPtr resultPtr = (CharStackPtr)malloc(sizeof(struct CharStack));
resultPtr->top = -1;
return resultPtr;
}//Of charStackInit
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
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
void pushPopTest() {
printf("---- pushPopTest begins. ----\r\n");
// Initialize.
CharStackPtr tempStack = charStackInit();
printf("After initialization, the stack is: ");
outputStack(tempStack);
// Pop.
for (char 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 ++) {
char ch = pop(tempStack);
printf("Pop %c.\r\n", ch);
outputStack(tempStack);
}//Of for i
printf("---- pushPopTest ends. ----\r\n");
}// Of pushPopTest
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.
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;
} // Of if
return true;
}// Of bracketMatching
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
int main() {
// pushPopTest();
bracketMatchingTest();
return 0;
}// Of main
运行结果:
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
三、表达式的值
#include <iostream>
#define MAXSIZE 100
#include <cstring>
#include <cmath>
#include <iomanip>
using namespace std;
struct likestack1
{
int top;
double date[MAXSIZE];
};
struct likestack2
{
int top;
char date[MAXSIZE];
};
template <class T1,class T2>
bool push(T1 *S,T2 e)
{
if(S->top==MAXSIZE-1)
return false;
S->top++;
S->date[S->top]=e;
return true ;
}
template <class T1,class T2>
bool pop(T1 *S,T2 *e)
{
if(S->top==-1)
return false;
*e=S->date[S->top];
S->top--;
return true;
}
template <class T1,class T2>
bool gettop(T1 *S,T2 *e)
{
if(S->top==-1)
return false;
*e=S->date[S->top];
return true;
}
template <class T>
bool likestackempty(T *S)
{
if(S->top==-1)
return true;
else
return false;
}
void like(likestack1 *S1,likestack2 *S2)
{
double b,a;
char e;
pop(S1,&a);
pop(S1,&b);
pop(S2,&e);
switch(e)
{
case '*':
push(S1,b*a);
break;
case '/':
push(S1,b/a);
break;
case '+':
push(S1,b+a);
break;
case '-':
push(S1,b-a);
break;
}
}
void change (char c[],int *k,int i,likestack1 *S1)
{
int a;
double b=0;
a=*k;
if(c[a+1]=='.')
{
b=c[a]-48;
a=a+2;
while(a<i)
{
b+=(c[a]-48)*pow(10,*k-a+1);
a++;
if(c[a]>'9'||c[a]<'0')
break;
}
push(S1,b);
*k=a-1;
}
else if(c[a+1]>='0'&&c[a+1]<='9')
{
a++;
while(c[a+1]<='9'&&c[a+1]>='0')
{
a++;
}
for(;*k<=a;*k=*k+1)//??
{
b+=(c[*k]-48)*pow(10,a-*k);
}
push(S1,b);
*k=*k-1;
}
else
push(S1,c[a]-48);
}
int main()
{
char c[100],d;
int i=0,k=0;
likestack1 *S1=new likestack1;
likestack2 *S2=new likestack2;
S1->top=-1;
S2->top=-1;
cin>>c;
i=strlen(c)-1;
for(;k<i;k++)
{
if(c[k]>='0'&&c[k]<='9')
change(c,&k,i,S1);
else
{
switch(c[k])
{
case '(':
push(S2,c[k]);
break;
case ')':
if(S2->date[S2->top]=='(')
pop(S2,&d);
else
like(S1,S2);
break;
case '+':
case '-':
if(likestackempty(S2)||S2->date[S2->top]=='(')
;
else
{
while(S2->date[S2->top]=='*'||S2->date[S2->top]=='/'||S2->date[S2->top]==')'||S2->date[S2->top]=='-'||S2->date[S2->top]=='+')
like(S1,S2);
}
push(S2,c[k]);
break;
case '*':
case '/':
if(S2->date[S2->top]!=')'&&S2->date[S2->top]!='*'&&S2->date[S2->top]!='/')
;
else
{
while(S2->date[S2->top]==')'||S2->date[S2->top]=='*'||S2->date[S2->top]=='/')
like(S1,S2);
}
push(S2,c[k]);
break;
}
}
}
while(1)
{
if(S2->top==-1)
break;
like(S1,S2);
}
cout<<fixed<<setprecision(2)<<S1->date[S1->top];
return 0;
}