1. 程式人生 > >字尾表示式的棧實現(C語言)

字尾表示式的棧實現(C語言)

中綴表示式轉為字尾表示式:

1.遇到運算元:直接輸出(新增到字尾表示式中)

2.棧為空時,遇到運算子,直接入棧

3.遇到左括號:將其入棧

4.遇到右括號:執行出棧操作,並將出棧的元素輸出,直到彈出棧的是左括號,左括號不輸出。

5.遇到其他運算子:加減乘除:彈出所有優先順序大於或者等於該運算子的棧頂元素,然後將該運算子入棧

6.最終將棧中的元素依次出棧,輸出。

計算字尾表示式:

1.如果是運算元,則放入棧中

2.如果是操作符,則取出棧中兩個運算元,進行運算後,將結果放入棧中;

3.直到最後棧中只有一個元素,此元素就是計算結果;

C語言實現:

stack.h

#ifndef _STACK_H
#define _STACK_H

struct StackRecord;
typedef struct StackRecord *Stack;
typedef int ElementType;

int IsEmpty(Stack S);
int IsFull(Stack S);
Stack CreateStack(int MaxElements);
void Free_Stack(Stack S);
void MakeEmpty(Stack S);
void Push(ElementType X, Stack S);
ElementType Top(Stack S);
void Pop(Stack S);
ElementType TopAndPop(Stack S);

#endif // _STACK_H

stack.c
#include <stdio.h>
#include <stdlib.h>
#include "stack.h"

#define EmptyTOS (-1)
#define MinStackSize (1)
struct StackRecord
{
    int Capacity;
    int TopOfStack;
    ElementType *Array;
};

Stack CreateStack(int MaxElements)
{
    Stack S;

    if(MaxElements < MinStackSize)
        printf("Stack Size is too small!\n");

    S = malloc(sizeof(struct StackRecord));
    if(S == NULL)
        printf("Out of Space, malloc Stack S failed\n");

    S->Array = malloc(sizeof(ElementType)*MaxElements);
    if(S->Array == NULL)
        printf("Out of Space, malloc S->Array failed\n");

    S->Capacity = MaxElements;

    return S;
}

void Free_Stack(Stack S)
{
    if(S != NULL)
    {
        free(S->Array);
        free(S);
    }
}

int IsEmpty(Stack S)
{
    return S->TopOfStack == EmptyTOS;
}

int IsFull(Stack S)
{
    return S->TopOfStack == S->Capacity - 1;
}

void MakeEmpty(Stack S)
{
    S->TopOfStack = EmptyTOS;
}

void Push(ElementType X, Stack S)
{
    if(IsFull(S))
        printf("Stack S is full\n");
    else
        S->Array[++S->TopOfStack] = X;
}

ElementType Top(Stack S)
{
    if(IsEmpty(S))
    {
        printf("Stack S is Empty\n");
        return -1;
    }
    else
        return S->Array[S->TopOfStack];
}

void Pop(Stack S)
{
    if(IsEmpty(S))
        printf("Stack S is Empty\n");
    else
        S->TopOfStack--;
}

ElementType TopAndPop(Stack S)
{
    if(IsEmpty(S))
    {
        printf("Stack S is Empty\n");
        return -1;
    }
    else
        return S->Array[S->TopOfStack--];
}

main.c
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "stack.h"

int IsOperator(char ch)
{
    char ops[] = "+-*/";
    int i;
    for (i = 0; i < 4; i++)
    {
        if (ch == ops[i])
            return 1;
    }
    return 0;
}


int Precedence(char op)
{
    if (op == '(')
    {
        return -1;
    }
    else if(op == '*' || op == '/')
        return 1;
    else if(op == '+' || op == '-')
        return 0;
}

void InFixtoPostFix(char *InFix, char *PostFix)
{
    int length = 0;
    int i = 0;
    int j = 0;
    length = strlen(InFix);
    Stack Experssion = CreateStack(length);
    MakeEmpty(Experssion);
    for(i = 0; i < length; i++)
    {
        if(InFix[i] == '(')
            Push(InFix[i],Experssion);
        else if(InFix[i] == ')')
        {
            while(Top(Experssion) != '(')
                PostFix[j++] = TopAndPop(Experssion);
            Pop(Experssion);
        }
        else
        {
            if(!IsOperator(InFix[i]))
                PostFix[j++] = InFix[i];
            else
            {
                while(IsEmpty(Experssion) == 0 && (Precedence(Top(Experssion))>=Precedence(InFix[i])))
                    PostFix[j++] = TopAndPop(Experssion);
                Push(InFix[i],Experssion);
            }
        }

    }

    while(IsEmpty(Experssion) == 0)
        PostFix[j++] = TopAndPop(Experssion);
    Free_Stack(Experssion);
    PostFix[j] = 0;
}

int Calcute(char *PostFix)
{
    int length = strlen(PostFix);
    int i = 0;
    int tmp_var = 0;
    int result_var = 0;
    Stack Calcute_stack = CreateStack(length);
    MakeEmpty(Calcute_stack);
    for(i = 0; i < length; i++)
    {
        if(IsOperator(PostFix[i]))
        {
            switch(PostFix[i])
            {
            case '+':
                tmp_var = TopAndPop(Calcute_stack) + TopAndPop(Calcute_stack);
                break;
            case '-':
                tmp_var = TopAndPop(Calcute_stack) - TopAndPop(Calcute_stack);
                break;
            case '*':
                tmp_var = TopAndPop(Calcute_stack) * TopAndPop(Calcute_stack);
                break;
            case '/':
                tmp_var = TopAndPop(Calcute_stack) / TopAndPop(Calcute_stack);
                break;
            }
            Push(tmp_var,Calcute_stack);
        }

        else
        {
            Push(PostFix[i] - '0',Calcute_stack);
        }
    }

    result_var = Top(Calcute_stack);
    Free_Stack(Calcute_stack);
    return result_var;
}
int main()
{
    char InFix[100];
    char PostFix[100];
    int Result = 0;

    while(1)
    {
        printf("please enter an expression: ");
        gets(InFix);
        printf("Infix is : %s \n",InFix);
        InFixtoPostFix(InFix,PostFix);
        printf("PostFix is : %s \n",PostFix);
        Result = Calcute(PostFix);
        printf("calculation is : %d \n",Result);
    }
    return 0;
}
中綴表示式轉為字尾表示式的結果