表达式求值

表达式在源码中经常出现,如何针对复杂的表达式进行分析计算是程序运行时必须解决的问题,请设计程序对满足如下要求的表达式进行分析,计算表达式的值。

1.操作数是十进制形式的多位整数或者实数。

2.运算符包括+,-,*,/,%。

3.界限符包括(),[ ],{ }。

4.若表达式合法,则输出表达式的值,否则提示表达式不合法。

#include<iostream>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>//C++中数学函数的头文件
using namespace std;
const int maxsize = 100;//定义常量
typedef struct
{
    double* top;//栈顶指针,指向当前栈顶元素的下一个
    double* base;//栈底指针
    int stacksize;//栈当前的长度,不包括后面分配的动态内存
} sta;
int init_stack(sta* s)//初始化栈
{
    s->base = (double*)malloc(maxsize * sizeof(double));//分配新空间
    if (!s->base)//判断栈是否成功初始化
    {

        return 0;
    }
    s->top = s->base;
    s->stacksize = maxsize;//栈的长度初始化
    return 1;
}
int push(sta* s, double m)//入栈函数,m作为新元素
{
    if (s->top - s->base == s->stacksize)//判断栈是否是满的
    {

        return 0;
    }
    *s->top = m;//把m的值赋值给栈顶指针所指向的位置
    s->top++;//栈顶指针+1,符合栈存储结构中栈顶指针的定义
    return 1;
}
int pop(sta* s, double* e)//出栈函数
{
    if (s->base == s->top)//有栈顶和栈底指针时判断栈空的条件
    {

        return 0;
    }
    s->top--;//栈顶指针-1,符合栈顶指针的定义
    *e = *s->top;
    return 1;
}
double gettop(sta* s)//获取栈顶元素
{
    if (s->base != s->top)//判断栈是否是空的
        return *(s->top - 1);
    else
        return 0;
}
double law(double a, double b, char c)//c作为字符,a和b分别是数字,用来计算二元表达式
{
    switch (c)
    {
    case'+':
        return a + b;
        break;
    case'-':
        return a - b;
        break;
    case'*':
        return a * b;
        break;
    case'/':
        if (b == '0')//除法要判断分母是否为0
        {
            cout << "分母不可以是0" << endl;
            return 1;
        }
        return a / b;
        break;
    case'%':
        return fmod(a, b);//引用了fmod函数,基本的a%b只能用于整型计算
        break;
    default:
        break;
    }
    return 0;
}
char compare(char a, char b)//运算符的优先级,在计算表达式中调用
{
 switch(a)
 {
  case'+':
  {
   if(b=='+'||b=='-'||b==')'||b=='=')
    return '>';
   else return '<';
   break;
  }
  case'-':
  {
   if(b=='+'||b=='-'||b==')'||b=='=')
    return '>';
   else return '<';
   break;
  }
  case'*':
  {
   if(b=='*'||b=='/'||b=='-'||b=='+'||b=='%'||b==')'||b==']'||b=='}'||b=='=')
    return '>';
   else return '<';
   break;
  }
  case'/':
  {
   if(b=='*'||b=='/'||b=='-'||b=='+'||b=='%'||b==')'||b==']'||b=='}'||b=='=')
    return '>';
   else return '<';
   break;
  }
  case'%':
    if(b=='*'||b=='/'||b=='-'||b=='+'||b=='%'||b==')'||b==']'||b=='}'||b=='=')
        return '>';
    else return '<';
    break;
  case'(':
  {
   if(b==')')
    return '=';
   else return '<';
   break;
  }
  case')':
  {
   return '>';
   break;
  }
  case'[':
    if(b==']')
        return '=';
    else return '<';
    break;
  case']':
   return '<';
   break;
   case'{':
    if(b=='}')
        return '=';
    else return '<';
    break;
  case'}':
   return '<';
   break;

  case'=':
   {
    if(b=='=')
     return '=';
    else return '<';
    break;
  default:
    break;
   }
 }
}
int yunsuanfu (char c)//运算符确定,如果不是已经规定的运算符则没有办法计算
{
    if (c == '(' || c == ')' || c == '[' || c == ']' || c == '{' || c == '}'
        || c == '+' || c == '-' || c == '*' || c == '/' || c == '%' || c == '=')
        return 1;
    else
        return 0;

}
double calculate(char flag[])//计算表达式的值,变量为数组,直接计算中缀表达式的值不用转化成后缀表达式
{
    sta n;//数字栈
    sta p;//运算符栈
   double a = 0, b = 0, c = 0, d = 0, f = 0;
    char ch[maxsize] = { 0 };//定义一个长度确定的数组并初始化,用该数组接收输入的一串字符
    int i = 0, j = 0;
    init_stack(&n);//初始化建立栈,否则栈不存在没有办法处理
    init_stack(&p);
    push(&p, '=');//将运算符栈的栈底存放=,用于和表达式中输入的=匹配判断运算结束

    ch[j] =flag[i++];//数组接收到字符后指针后移

    while (ch[j] != '=' || gettop(&p) != '=')//输入字符结束的判断条件
    {
        if (isdigit(ch[j]) || ch[j] == '.')//isdigit函数是判断是否为0到9的数字,判断是否为数字或者小数点
        {
            if (isdigit(ch[j]))
            {
               d = ch[j]-'0';//接收进来的都是字符,因此要转化成十进制数字
                push(&n, d);//数字入栈
                f = d;
                ch[j] =flag[i++];//指针后移

                while (isdigit(ch[j]))//判断下一个字符是不是数字
                {
                    pop(&n, &d);//把之前的数字弹出,和现在的数字结合转化成十进制数
                    d = ch[j]-'0';
                    f= 10 * f + d;//转化成十进制数
                   push(&n, f);//数字入栈
                    ch[j] = flag[i++];
                }
                if (ch[j] == '.')//判断是不是小数
                {

                   pop(&n, &f);//前面一个数字出栈
                    ch[j] = flag[i++];
                    int nn = 0;
                    for (nn; isdigit(ch[j]); nn++)
                    {
                       d = ch[j] - '0';//当前数字转化成十进制数
                        f= 10 * f +d;//计算前一个数字也就是小数点后的值
                        ch[j] = flag[i++];
                    }
                    f = f / (pow(10, nn));//化成小数
                   push(&n, f);

                }
            }
        }
        else if (yunsuanfu(ch[j]))//运算符处理
        {
            switch (compare(gettop(&p), ch[j]))
            {
            case '<'://小于,不能运算暂且先入栈
                push(&p, ch[j]);
                ch[j] = flag[i++];
                break;
            case '>'://大于,取出数字栈两个元素和运算符栈一个元素并调用law()函数进行运算
                pop(&p, &c);
                pop(&n, &b);
                pop(&n, &a);
                push(&n, law(a, b, c));
                break;
            case '='://相等的时候出栈字符再比较,指针后移
                pop(&p, &c);
                ch[j] =flag[i++];
                break;
            }

        }
    }
    return(gettop(&n));//数字栈最后的元素就是计算结果
}
int main()
{
    cout << "输入表达式求值" << endl;
    char flag[maxsize];//读取字符串的数组
    int ture = 1;
    while (ture)
    {
        cout << "请输入表达式(=结束):";
        cin >> flag;
        cout << endl << "表达式的值为:" << calculate(flag)<< endl;//调用函数calculate()进行运算
        cout << "按任意键继续......" << endl;
        cin >> ture;
    }
    return 0;
}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Python表达式是指根据给定的Python表达式计算出结果的过程。它涉及解析表达式,按照运算符的优先级和结合性进行计算,并返回最终的结果。 在上述引用中,提到了一种方法来编程演示如何一步一步地计算Python表达式。这种方法涉及使用ast模块解析表达式为抽象语法树(AST),然后逐步AST节点。首先,使用ast.parse()将字符串解析为AST。然后,找到一个首先要的节点,并使用eval(compile(node, '', 'eval'))对其结果可以转换回AST节点,并用结果节点替换当前节点。接着,使用codegen.to_source从修改后的AST生成修改后的代码字符串,并继续相同的过程,直到树中只有一个节点。 这种方法可以逐步展示Python表达式过程。它可以用于教学目的,帮助学生理解表达式方式。然而,需要注意的是,这种方法可能无法处理某些复杂的行为,比如列表理解。在处理这些复杂情况时,可能需要采用其他方法或工具。 总结:Python表达式是根据给定的表达式计算结果的过程。使用ast模块可以解析表达式为AST,并通过逐步AST节点来展示过程。然而,对于复杂的行为,可能需要其他方法或工具来处理。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [逐步跟踪Python表达式](https://blog.csdn.net/weixin_30982943/article/details/112956371)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值