栈的应用——四则运算表达式(逆波兰算法)

基本思路:
首先定义两个栈,一个存放数字,一个存放符号。
存放数字的栈:
只有当后面的一位是符号时才入栈,这是因为如果是一个多位数的情况。

存放符号的栈:
1.当符号栈为空或者是a[i] 不是 ‘)’并且栈顶元素是‘(’时或者符号优先级大于栈顶元素的优先级时入栈。
2.当a[i] 是 ‘)’并且栈顶元素是‘(’时,弹出栈顶元素,即括号成对了,把左括号删除。
3.当a[i] 是 ‘)’并且栈顶元素不是‘(’时或者符号优先级小于等于栈顶元素的优先级时或者表达式结束,但是符号栈不为空时进行相应的加减乘除运算。

最后数字栈里只有一个元素就是最后的运算结果。

直接放代码:

#include <stdio.h>
#include <stdlib.h>

#define SUCCESS  0
#define FAILURE -1

struct node
{
    int data;
    struct node *next;
};

typedef struct node Node;

struct stack
{
    Node *top;
    int count;
};

typedef struct stack LinkStack;

int StackInit(LinkStack *S)
{
    S->top = NULL;
    S->count = 0;

    return SUCCESS;
}

int StackPush(LinkStack *S, int e)
{
    if(S == NULL)
    {
        return FAILURE;
    }

    Node *p = (Node *)malloc(sizeof(Node));
    if(p == NULL)
    {
        return FAILURE;
    }

    p->data = e;
    p->next = S->top;
    S->top = p;
    S->count++;

    return SUCCESS;
}

int StackEmpty(LinkStack *S)
{
    if(S == NULL)
    {
        return FAILURE;
    }

    if(S->count == 0)
    {
        return SUCCESS;
    }

    else
    {
        return FAILURE;
    }
}

int StackGetTop(LinkStack *S)
{
    if(S->top == NULL)
    {
        return FAILURE;
    }

    return (S->top->data);
}

int StackPop(LinkStack *S)
{
    if(S->top == NULL)
    {
        return FAILURE;
    }

    int e;
    Node *p = (Node *)malloc(sizeof(Node));
    if(p == NULL)
    {
        return FAILURE;
    }

    p = S->top;
    e = S->top->data;
    S->top = S->top->next;
    free(p);
    S->count--;

    return e;
}

int Priority(char c)
{
    switch(c)
    {
        case '(':
            return 3;

        case '*':
        case '/':
            return 2;

        case '+':
        case '-':
            return 1;

        default:
            return 0;
    }
}

int main()
{
    char a[100] = {0};
    int ret, i = 0;
    int temp = 0, j;
    LinkStack opt, num;

    if(StackInit(&num) != SUCCESS || StackInit(&opt) != SUCCESS)
    {
        return FAILURE;
    }

    printf("Please input a option:\n");
    scanf("%s", a);

    while(a[i] != '\0' || (StackEmpty(&opt) != SUCCESS))
    {
        if(a[i] >= '0' && a[i] <= '9')
        {
            temp = temp * 10 + a[i] - '0';
            i++;

            if(a[i] < '0' || a[i] > '9')
            {
                StackPush(&num, temp);
                temp = 0;
                continue;
            }
        }

        else
        {
            if((StackEmpty(&opt) == SUCCESS) || (StackGetTop(&opt) == '(' && a[i] != ')') || (Priority(a[i]) > Priority(StackGetTop(&opt))))
            {
                StackPush(&opt, a[i]);
                i++;
                continue;
            }

            if(a[i] == ')' && StackGetTop(&opt) == '(')
            {
                StackPop(&opt);
                i++;
                continue;
            }

            if((a[i] == ')' && StackGetTop(&opt) != '(') || (Priority(a[i]) <= Priority(StackGetTop(&opt))) || (a[i] == '\0' && StackEmpty(&opt) != SUCCESS))
            {
                switch(StackPop(&opt))
                {
                    case '+':
                    StackPush(&num, StackPop(&num) + StackPop(&num));
                    break;

                    case '-':
                    j = StackPop(&num);
                    StackPush(&num, StackPop(&num) - j);
                    break;

                    case '*':
                    StackPush(&num, StackPop(&num) * StackPop(&num));
                    break;

                    case '/':
                    j = StackPop(&num);
                    StackPush(&num, StackPop(&num) / j);
                    break;

                    default:
                    break;
                }
                continue;
            }
        }
    }

    printf("The result is %d\n", StackPop(&num));


    return 0;
}
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值