用逆波兰表达式完成简单计算器

definition.h

#pragma once
#include<stdio.h>
#include<windows.h>
#include<assert.h>
#define len 10
#define Stack_size 20
typedef enum comput //运算
{
    OP_NUM=1,//操作数
    OP_SYMBOL=2,//操作符:加减乘除
    OP_ADD=3,   
    OP_SUB=4,
    OP_MUL=6,
    OP_DIV=7,
}comput;

typedef struct Cell //顺序表内,栈内存储的元素(有两个成员)
{
    comput _type;//类型:操作数/操作符
    int value;   //      数值/(add/sub/mul/div)
}Cell;
typedef Cell DataType;

typedef struct Stack
{
    DataType* _array;//数组指针
    size_t  _top; //栈顶 
    size_t  _end;//最大容量
}Stack;

typedef struct SeqList
{
    DataType *a;
    size_t size;
    size_t capacity;
}SeqList;

test.c

#include"functions.h"
// 思路:
//1.用户输入前缀表达式,将式存入顺序表A
//2.将前缀表达式转化为后缀表达式,并存入顺序表B中
//3.对B内后缀表达式运算(借助一个栈临时存储操作符),并输入结果
void test()
{

    SeqList list, list1;
    Stack s;
    SeqInit(&list);
    SeqInit(&list1);
    StackInit(&s);
    SeqPushBack(&list, OP_NUM, 3);
    SeqPushBack(&list, OP_SYMBOL, OP_MUL);
    SeqPushBack(&list, OP_NUM, 4);
    SeqPushBack(&list, OP_SYMBOL, OP_ADD);
    SeqPushBack(&list, OP_NUM, 2);
    //34*2+
    turn_reverse_polish_expression(&list, &list1, &s);//前缀表达式转后缀表达式
    for (size_t i = 0;i < list1.size;i++)
    {
        printf("%2d", list1.a[i]._type);
        printf("%2d\n", list1.a[i].value);
    }
    int i= comput_reverse_polish_expression(&list1,&s);//计算后缀表达式
    printf("结果为%d\n", i);
}


int main()
{
    test();
    system("pause");
    return 0;
}

seqlist.h

#pragma once
#include"definition.h"
void SeqInit(SeqList* pSeq)
{
    //初始化顺序表:分配内存,将已用长度置零,全长为len
    assert(pSeq);
    pSeq->a = (DataType*)malloc(sizeof(DataType)*len);
    pSeq->size = 0;
    pSeq->capacity = len;
}

void Seqcheckfull(SeqList **pSeq)
{
    //检查顺序表是否满
    if ((*pSeq)->size == (*pSeq)->capacity)
    {
        (*pSeq)->a = (DataType*)realloc((*pSeq)->a, sizeof(DataType)*len * 2);
        (*pSeq)->capacity *= 2;
    }
}

void SeqPushBack(SeqList* pSeq, comput _type, int value)
{
    //判断是否满,满则用realloc多分配一倍内存。未满将数据存在最后,size++
    assert(pSeq);
    Seqcheckfull(&pSeq);
    pSeq->a[pSeq->size]._type = _type;
    pSeq->a[pSeq->size].value = value;
    pSeq->size++;
}
void SeqDestory(SeqList* pSeq)
{
    //销毁顺序表:free掉头数据区头指针,置为空,在把已用长度和总长置零
    assert(pSeq);
    free(pSeq->a);
    pSeq->a = NULL;
    pSeq->capacity = 0;
    pSeq->size = 0;
}

void SeqPopBack(SeqList* pSeq)
{
    //判断顺序表是否为空,空则报错返回,未空则size--
    assert(pSeq);
    if (pSeq->size == 0)
    {
        printf("SeqList is empty!");
        assert(0);
    }
    pSeq->size--;
}

stack1.h

#pragma once
#include"definition.h"
// 栈的实现接口 
void StackInit(Stack* s)//栈的初始化
{
    assert(s);
    s->_array = (DataType*)malloc(sizeof(DataType)*Stack_size);
    s->_end = Stack_size;
    s->_top = 0;

}

void StackPush(Stack* s, comput _type,int value)//入栈
{
    assert(s);
    if (s->_end == s->_top)//栈已满
    {
        s->_end *= 2;
        s->_array = (DataType*)realloc(s->_array, sizeof(DataType)*(s->_end));

    }
        s->_array[s->_top]._type = _type;
        s->_array[s->_top].value = value;
        (s->_top)++;

}

void StackPop(Stack* s)//出栈
{
    assert(s);
    if (s->_top == 0)
    {
        printf("the stack is empty");
    }
    else
    {
        s->_top--;
    }
}

DataType StackTop(Stack* s)//取栈顶元素
{
    assert(s);
    if (s->_top == 0)
    {
        assert(0);

    }

        int num = s->_top;
        DataType i = s->_array[(--num)];
        return i;


}

int StackEmpty(Stack* s)//判断栈是否为空
{
    if (s->_top == 0)
    {
        return 1;
    }
    else
    {
        return 0;
    }
}

functions.h

#pragma once
#include"stack1.h"
#include"seqlist.h"

void turn_reverse_polish_expression(SeqList *list, SeqList *list1, Stack *s)
{
    //1.从list开始读,遇到操作数就存入list1.栈为空时遇到操作符就入栈
    //当再次遇到操作符时,仅有该操作符优先级>栈顶操作符优先级时,才入栈,否则,将顺序表内倒数2个
    //取出,倒2作左值,倒一作右值,运算过后再将新数存入顺序表,将当前操作符存入s
    //直至list1长度与list相等
    assert(list);
    assert(list1);
    assert(s);
    DataType *cur = list->a;
    size_t size = list->size;
    while (size)
    {
        if (cur->_type == OP_NUM)//遇到操作数
        {
            SeqPushBack(list1, cur->_type, cur->value);
        }
        if (cur->_type == OP_SYMBOL)//遇到操作符
        {
            if (StackEmpty(s) == 1 || cur->value - StackTop(s).value>=2)//当前操作符的优先级比栈顶操作符优先级高||栈为空
            {
                StackPush(s, cur->_type, cur->value);
            }
            else
            {
                while (StackEmpty(s)==0 && (cur->value- StackTop(s).value<2))
                {
                    SeqPushBack(list1, StackTop(s)._type, StackTop(s).value);
                    StackPop(s);
                }

                StackPush(s, cur->_type, cur->value);
            }


        }
        size--;
        cur++;
    }
    if (StackEmpty(s) == 0)//如果顺序表list已经走到尾,则应该判断栈s是否为空,如果不为空则补在list1后面。
    {
        while (StackEmpty(s) != 1)
        {
            SeqPushBack(list1, StackTop(s)._type, StackTop(s).value);
            StackPop(s);
        }
    }
}

int comput_reverse_polish_expression(SeqList *list1, Stack *s)
{
    assert(list1);
    assert(s);

    DataType *cur = list1->a;
    size_t size = list1->size;
    while (size)  // 34*2+
    {
        if (cur->_type == OP_NUM)
        {
            StackPush(s, cur->_type, cur->value);
            size--;
            cur++;
        }
        if (cur->_type == OP_SYMBOL)
        {
            int newnum = 0;
            int right = StackTop(s).value;
            StackPop(s);
            int left = StackTop(s).value;
            StackPop(s);

            switch (cur->value)
            {
            case OP_ADD:
            {
                newnum = left + right;
                break;
            }
            case OP_SUB:
            {
                newnum = left - right;
                break;
            }
            case OP_MUL:
            {
                newnum = left*right;
                break;
            }
            case OP_DIV:
            {
                newnum = left / right;
                break;
            }
            default:
                break;

            }
            StackPush(s, cur->_type, newnum);
            size--;
            cur++;
        }

    }
    return StackTop(s).value;
}

猜你喜欢

转载自blog.csdn.net/ferlan/article/details/79921837