BUAA_数据结构_4TH_计算器(表达式计算-后缀表达式实现)

BUAA_数据结构_4TH_计算器(表达式计算-后缀表达式实现)

题目描述:

从标准输入中读入一个整数算术运算表达式,如24 / ( 1 + 5%3 + 36 / 6 / 2 - 2) * ( 12 / 2 / 2 )= ,计算表达式结果,并输出。
要求:
1、表达式运算符只有+、-、*、/、%,表达式末尾的=字符表示表达式输入结束,表达式中可能会出现空格;
2、表达式中会出现圆括号,括号可能嵌套,不会出现错误的表达式;
3、出现除号/时,以整数相除进行运算,结果仍为整数,例如:5/3结果应为1。
4、要求采用逆波兰表达式来实现表达式计算。

输入形式

从键盘输入一个以=结尾的整数算术运算表达式。操作符和操作数之间可以有空格分隔。

输出形式

在屏幕上输出计算结果(为整数,即在计算过程中除法为整除)。

思路

最朴素的思路应为中缀转后缀 之后进行运算
但这里我们采用在转换的同时进行计算的思路。
具体思路如下:
设立两个栈:数据栈和符号栈
从输入的表达式中获取一个元素:
若此元素为数字则压入数据栈(此处需要考虑如何处理1234,254,这类>=10的数字 处理方法在下面代码中 有需要可以酌情参考)
若此元素不为数字:

  1. 为等号:跳出循环 并不断弹栈进行运算
  2. 为空格:continue即可
  3. 为):不断弹栈并计算直到符号栈中弹出(
    (此处注意弹出(之后不进行计算)
  4. 为(,+,*,/,-则从符号栈中弹出优先级高于当前的符号并与数据栈元素进行运算 将计算结果压回数据栈中 知道遇到一个优先级低的符号 然后将当前符号压入栈中

易错点

  1. 栈空的时候进行弹栈/查看栈顶元素操作
  2. 未处理空格
  3. 遇到等号跳出循环之后未对仍在栈中的元素进行运算
  4. 符号优先级
  5. 数字处理

参考代码

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<ctype.h>
#define maxN 200
char middle[maxN+10];
char op_stack[maxN+10];
int pos_op;
int num_stack[maxN+10];
int pos_num;

int is_empty();
int is_full();
void push(char x);
char pop();
char look();
void push_num(int x);
int pop_num();
int is_number(char x);
int cal(char op,int num1,int num2);
int get_pri(char x);

int main()
{
    pos_op=-1;
    pos_num=-1;
    int num1,num2;
    int cal_temp;
    char op;
    gets(middle);
    int len=strlen(middle);
    for(int i=0;i<len;i++){
        if(is_number(middle[i])){
            int num=0;
            while(is_number(middle[i])){
                num=num*10+middle[i]-'0';
                i++;
            }
            push_num(num);
        }
        if(middle[i]==' ') continue;
        if(middle[i]=='=') break;
        if(middle[i]==')'){
            while(1){
                op=pop();
                if(op=='(') break;
                num2=pop_num();
                num1=pop_num();
                cal_temp=cal(op,num1,num2);
                push_num(cal_temp);
            }
        }
        else{
            if(is_empty()){
                push(middle[i]);
                continue;
            }
            char stack_top=look();
            while(get_pri(stack_top)>=get_pri(middle[i])){
                if(stack_top=='(') break;
                op=pop();
                num2=pop_num();
                num1=pop_num();
                cal_temp=cal(op,num1,num2);
                push_num(cal_temp);
                if(is_empty()) break;
                stack_top=look();
            }
            push(middle[i]);
        }
    }
    while(!is_empty()){
        op=pop();
        num2=pop_num();
        num1=pop_num();
        cal_temp=cal(op,num1,num2);
        push_num(cal_temp);
    }
    int res=pop_num();
    printf("%d\n",res);
    return 0;
}

int is_empty()
{
    if(pos_op==-1){
        return 1;
    }
    else{
        return 0;
    }
}

int is_full()
{
    if(pos_op==maxN-1){
        return 1;
    }
    else{
        return 0;
    }
}

void push(char x)
{
    op_stack[++pos_op]=x;
}

char pop()
{
    char res=op_stack[pos_op];
    op_stack[pos_op]='\0';
    pos_op--;
    return res;
}

char look()
{
    return op_stack[pos_op];
}

int is_number(char x)
{
    if(x>='0'&&x<='9') return 1;
    else return 0;
}

void push_num(int x)
{
    num_stack[++pos_num]=x;
}

int pop_num()
{
    int res=num_stack[pos_num];
    num_stack[pos_num]='\0';
    pos_num--;
    return res;
}

int cal(char op,int num1,int num2)
{
    switch(op){
        case '+':
            return num1+num2;
        case '-':
            return num1-num2;
        case '*':
            return num1*num2;
        case '/':
            return num1/num2;
        case '%':
            return num1%num2;
    }
}

int get_pri(char x)
{
    switch(x){
        case '+':
            return 0;
        case '-':
            return 0;
        case '*':
            return 1;
        case '/':
            return 1;
        case '%':
            return 1;
        case '(':
            return 2;
        case ')':
            return 2;
    }
}

有问题或bug 欢迎私戳/评论

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值