数据结构实验4

7-2 栈实现表达式求值
使用键盘输入数学表达式(含数字,四种运算符+、-、、/和小括号,其中运算数都是一位数(0~9)),将数学表达式转化成后缀表达式输出,利用后缀表达式求表达式的值并输出。

输入格式:
输入正确的表达式(可以有空格)后回车,得到后缀表达式和结果。输入括号缺失的表达式,输出"ERROR:缺少括号"。输入两个除括号外运算符连续的表达式,输出"ERROR:表达式缺操作数"。

输出格式:
请在这里描述输出格式。例如:对每一组输入,在一行中输出A+B的值。

输入样例:
在这里给出一组输入。例如:

5*(8-(3+2))
输出样例:
在这里给出相应的输出。例如:

5832+-*
15

代码:

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

#define MAX_SIZE 100

//运算符优先级
int precedence(char op){
    if(op=='+'||op=='-')
        return 1;
    if(op=='*'||op=='/')
        return 2;
    return 0;
}

//判断是否为操作数
int isOperand(char ch){
    return isdigit(ch);
}

//判断是否为运算符
int isOperator(char ch){
    return (ch=='+'||ch=='-'||ch=='*'||ch=='/');
}

//判断括号是否匹配
int isValidExpression(char *expr){
    int balance=0;
    for(int i=0;expr[i]!='\0';i++){
        if(expr[i]=='(')
            balance++;
        if(expr[i]==')')   //右括号多于左括号
            balance--;
        if(balance<0)   //左右括号数量是否相等
            return 0;
    }
    return(balance==0);
}

//转换为后缀表达式并计算值
void evaluate(char *expr){
    char stack[MAX_SIZE];
    int top=-1;
    char postfix[MAX_SIZE];
    int postIndex=0;

    if(!isValidExpression(expr)){
        printf("ERROR:缺少括号\n");
        return;
    }

    //处理操作符和数
    for(int i=0;expr[i]!='\0';i++){
        char current=expr[i];

        //跳过空格
        if(current==' ')
            continue;

        //如果时操作数,直接添加到后缀表达式
        if(isOperand(current)){
            int num=0;
            while(isdigit(expr[i])){
                num=num*10+(expr[i]-'0');
                i++;
            }
            postfix[postIndex++]=num;
            i--;
        }
        //如果是左括号,压入栈
        else if(current=='('){
            stack[++top]=current;
        }
        //如果是右括号,弹出之道遇到左括号
        else if(current==')'){
            while(top>=0&&stack[top]!='('){
                postfix[postIndex++]=stack[top--];
            }
            if(top<0){
                printf("ERROR:缺少括号\n");
                return ;
            }
            top--;
        }
        //如果是运算符
        else if(isOperator(current)){
            //弹出栈中优先级大于等于当前运算符的所有运算符
            while(top>=0&&precedence(stack[top])>=precedence(current)){
                postfix[postIndex++]=stack[top--];
            }
            stack[++top]=current;
        }else{
            printf("ERROR:无效字符\n");
            return ;
        }
    }

    //将栈中剩余的运算符添加到后缀表达式
    while(top>=0){
        if(stack[top]=='('){
            printf("ERROR:缺少括号\n");
            return;
        }
        postfix[postIndex++]=stack[top--];
    }
    postfix[postIndex]='\0';   //后缀表达式结束
    printf(":%s\n",postfix);

    //计算后缀表达式的值
    int result[MAX_SIZE];
    int resultIndex=-1;

    for(int i=0;postfix[i]!='\0';i++){
        char current=postfix[i];

        if(isOperand(current)){
            result[++resultIndex]=current-'0';
        }else if(isOperator(current)){
            if(resultIndex<1){
                printf("ERROR:表达式缺操作数\n");
                return;
            }
            int b=result[resultIndex--];
            int a=result[resultIndex--];
            switch(current){
                case '+':result[++resultIndex]=a+b;break;
                case '-':result[++resultIndex]=a-b;break;
                case '*':result[++resultIndex]=a*b;break;
                case '/':
                    if(b==0){
                    printf("ERROR:除数不能为0\n");
                    return;
                }
                result[++resultIndex]=a/b;
                    break;
            }
        }
    }
    if(resultIndex!=0){
        printf("ERROR:表达式缺操作数");
        return ;
    }
    printf("%d\n",result[resultIndex]);
}

int main(){
    char expr[MAX_SIZE];

    //输入数学表达式
    if(fgets(expr,MAX_SIZE,stdin)==NULL){
        printf("ERROR:输入错误\n");
        return 1;
    };

    //去除输入末尾的换行符
    expr[strcspn(expr,"\n")]='\0';

    //处理表达式
    evaluate(expr);
    return 0;
}
posted @   呓语-MSHK  阅读(5)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· 一文读懂知识蒸馏
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
点击右上角即可分享
微信分享提示