用栈实现计算器

我们平时用swith语句写的计算器,只能处理简单的两个操作数和一个运算符,这样其实和日常应用方面差的有点远,所以我们今天学习了一种用栈来实现一条复杂运算式的计算。这个需要用到栈的相关知识,除此之外我们还需要学会如何把中缀转换成后缀表达式,比如:3+(4+5*2)-3这样一个表达式,从左至右遇到操作数压入栈1,遇到操作符压入栈2,当栈2的栈顶元素为空或者栈顶为‘(’ 时无脑压进栈,遇到右括号‘)’时出栈;遇到操作符的优先级大于栈顶元素的优先级时栈顶元素出栈同时去操作数的前两个进行运算,先把上式做一下:

栈1 : 栈底---->栈顶3 4 5 2  ---->   3   4   10  ------>3   14

 栈2:  栈底---->栈顶+ ( + *)此时先取*与2和5相乘得到10压入栈1在去两个元素进行 +即4和10

得到:栈1    3   14     ------->   17 --------->17  3

          栈2:   +    ‘-’的优先级不大于+所以栈顶的元素出栈即进行 3+14 = 17 --------->-

最终得到17 - 3 = 14

重要:当运算符出栈时,拿操作数栈里的次于栈顶元素去加减乘除栈顶元素

 

 

这是在用栈实现计算器时所有需要考虑的因素,代码如下:头文件部分前面也有详细说明重复贴代码了

#include<stdio.h>
#include"linkstack.h"

int perorty(char ch)
{
    switch(ch)
    {
        case '(':
            return 3;
        case '*':
        case '/':
            return 2;
        case '+':
        case '-':
            return 1;
        default:
            return 0;
    }
}
int main()
{
    Stack *s_num, *s_opt;
    char opt[1024] = {0};
    int i = 0, num1 = 0, num2 = 0, tmp = 0;
    if((LinkStackInit(&s_num) != success) || (LinkStackInit(&s_opt) != success))
    {
        printf("Init failure!\n");
    }

    printf("input:\n");
    scanf("%s",opt);
    while(opt[i] !='\0'|| StackEmpty(s_opt) != TRUE)
    {
        if(opt[i] > '0' && opt[i] < '9')
        {
           tmp = tmp * 10 + opt[i] - '0';
           i++;
           if(opt[i] > '9' || opt[i] < '0')
           {
               Push(s_num, tmp) ;
               tmp = 0;
                
           }
        }
        else
        {
            if(opt[i] == ')' && GetTop(s_opt) == '(')
            {
                Pop(s_opt);
                i++;
          //      continue;
            }
            if(StackEmpty(s_opt) == TRUE || (perorty(opt[i]) > perorty(GetTop(s_opt))) 
                    || (GetTop(s_opt) == '(' && opt[i] != ')'))
            {
                Push(s_opt, opt[i]);
                i++;
        //        continue;
            }
            if((opt[i] == '\0' && StackEmpty(s_opt) != TRUE) || 
                    (opt[i] == ')' && GetTop(s_opt) != '(') ||
                    perorty(opt[i] <= perorty(GetTop(s_opt))))
            {
                switch(Pop(s_opt))
                {
                    case '+':
                        num1 = Pop(s_num);
                        num2 = Pop(s_num);
                        Push(s_num, (num1 + num2));
                        break;
                    case '-':
                        num1 = Pop(s_num);
                        num2 = Pop(s_num);
                        Push(s_num, (num2 - num1));
                        break;
                    case '*':
                        num1 = Pop(s_num);
                        num2 = Pop(s_num);
                        Push(s_num, (num2 * num1));
                        break;
                    case '/':
                        num1 = Pop(s_num);
                        num2 = Pop(s_num);
                        Push(s_num, (num2 / num1));
                        break;
                    default :
                        printf("error opt!\n");
                        break;
                }
            }
        }
    }
    printf("%d\n", GetTop(s_num));
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值