令人抓狂的四则运算pta c语言

曾记否,我们小学时,遇到这种四则运算,心情是抓狂的:

 

 

那么当我们学会使用计算机,自然是要程序去完成这个工作啦~ 现在请对输入的四则运算求值。注意:

  • 四则运算表达式必定包含运算数,还可能包含运算符和括号( )不含空格等其它字符
  • 运算数必定包含数字,还可能包含正或负符号+-以及小数点.
  • 运算符仅有+(加)、-(减)、*(乘以)、/(除以)四种
  • 括号可以嵌套
  • 对于带符号的数,可以加括号,也可以不加括号,例如:1+-2*+31+(-2)*(+3)是等价的
  • 括号内可以是包含运算符的表达式,也可以仅有运算数,例如:1*(2)1*(2+3)都是合法的表达式

输入格式:

输入由若干行组成:

  • 除最后一行之外,每一行是一个长度不超过80的四则运算表达式
  • 最后一行,是一个=字符

输入的所有字符均为英文半角字符,题目保证给定的表达式是正确的,不需要做有效性检查,题目保证所有运算数的长度(含小数点)均不超过5位,运算的中间结果和最终结果的绝对值均不超过100000

输出格式:

对输入的每个表达式,在一行中给出运算结果,保留1位小数。

输入样例:

1
1+2
3-3.8
1.32*(4+(-2))
=

输出样例:

1.0
3.0
-0.8
2.6

 题解如下:

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

char s[100];
double stk_num[100];
char stk_fu[100];

int is_number(char c)
{
    return c >= '0' && c <= '9' || c == '.';
}

int check(char a, char b)
{
    if(a == '+' || a == '-')
    {
        if(b == '+' || b == '-')return 0;
        else return 1;
    }
    else if(a == '*' || a == '/')
    {
        if(b == '(')return 1;
        else return 0;
    }
    else if(a == '(')
    {
        if(b == ')')return 0;
        else return 1;
    }
}

double fun(double a, char c, double b)
{
    if(c == '-')return b - a;
    if(c == '+')return b + a;
    if(c == '*')return b * a;
    if(c == '/')return b / a;
}

int main()
{
    int len;
    int top_num;
    int top_fu;
    while(1)
    {
        scanf("%s", s);
        if(s[0] == '=')break;
        len = strlen(s);
        top_num = 0, top_fu = 0;
        for(int i = 0; i < len; i++)
        {
            // printf("i = %d top_num = %d top_fu = %d\n", i, top_num, top_fu);
            // for(int m = 1; m <= top_num; m++)printf("%f ",stk_num[m]);
            // printf("\n");
            // for(int m = 1; m <= top_fu; m++)printf("%c ", stk_fu[m]);
            // printf("\n");
            //处理数字部分
            if(is_number(s[i]))
            {
                double number = 0;
                
                int j, k;
                for(j = i; j < len && s[j] != '.' && is_number(s[j]) != 0; j++)
                    number = number * 10 + s[j] - '0';
                
                k = j;
                
                if(s[j] =='.')
                {
                    double m = 0.1;
                    for(k = j + 1; k < len && is_number(s[k]) != 0; k++)
                    {
                        number += m * (s[k] - '0');
                        m /= 10;
                    }
                }
                if(i == 1 && s[0] == '-' || i > 1 && s[i - 1] == '-' && is_number(s[i - 2]) == 0)
                    number *= -1;
                i = k - 1;
                stk_num[++top_num] = number;
            }
            // 处理符号部分
            else 
            {
                //将非符号部分排除
                if((s[i] == '+' || s[i] == '-') && (i == 0 || s[i - 1] == '(' || (is_number(s[i - 1]) == 0 && s[i - 1] != ')')))
                    continue;
                //讨论当 ')' 时的情况
                if(s[i] == ')')
                {
                    while(stk_fu[top_fu] != '(')
                    {
                        double a = stk_num[top_num--], b = stk_num[top_num--];
                        char c = stk_fu[top_fu--];
                        stk_num[++top_num] = fun(a, c, b);
                    }
                    top_fu--;
                }
                else 
                {
                    //普通情况
                    if(top_fu == 0)stk_fu[++top_fu] = s[i];
                    else 
                    {
                        //如若s[i]大一级直接压栈 否则拿出来计算
                        if(check(stk_fu[top_fu], s[i]) == 1)stk_fu[++top_fu] = s[i];
                        else 
                        {
                            //当符号栈为空或符号栈定优先级更大位置
                            while(top_fu != 0 && check(stk_fu[top_fu], s[i]) == 0)
                            {
                                double a = stk_num[top_num--], b = stk_num[top_num--];
                                char c = stk_fu[top_fu--];
                                stk_num[++top_num] = fun(a, c, b);
                            }
                            stk_fu[++top_fu] = s[i];
                        }
                    }
                }
            }
        }
        while(top_fu != 0)
        {
            double a = stk_num[top_num--], b = stk_num[top_num--];
            char c = stk_fu[top_fu--];
            stk_num[++top_num] = fun(a, c, b);
        }
        printf("%.1f\n", stk_num[top_num]);
    }
    return 0;
}

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值