数据结构C:栈、栈的应用——括号匹配、表达式求值

一、栈 

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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值