题意

给出一个表达式,其中运算符仅包含+,-,*,/,^(加 减 乘 整除 乘方)要求求出表达式的最终值

数据可能会出现括号情况,还有可能出现多余括号情况

数据保证不会出现>=2^31的答案

数据可能会出现负数情况

表达式总长度<=30

分析

参照机械能战士的题解。

此处不使用栈求表达式值的算法, 而使用递归算法, 注意题目中指出表达式中可能存在多余括号, 因此应首先去除多余括号得到等价的合法表达式(使用栈进行配对即可), 接下来将表达式长度视为问题的规模, 为减小问题的规模实现递归, 根据运算符优先级特点, 如果表达式中存在不在任何括号中的加减号, 那么将最后一个不在任何括号中的加减号作为表达式分割点, 如果存在表达式中存在不在任何括号中的乘除号, 那么将最后一个不在任何括号中的乘除号作为表达式分割点, 否则以最后一个不在任何括号中的乘方号作为表达式的分割点, 下面给出基于此思想AC代码(实际上, 可通过对表达式长度进行数学归纳, 证明下述程序能正确计算表达式的值, 具体证明过程此处不再赘述)

代码

#include<bits/stdc++.h>
#define rg register
#define il inline
#define co const
template<class T>il T read(){
    rg T data=0,w=1;
    rg char ch=getchar();
    while(!isdigit(ch)){
        if(ch=='-') w=-1;
        ch=getchar();
    }
    while(isdigit(ch))
        data=data*10+ch-'0',ch=getchar();
    return data*w;
}
template<class T>il T read(rg T&x){
    return x=read<T>();
}
typedef long long ll;
using namespace std;

co int MAX=35,NIL=0x3f3f3f3f;
char cstr[MAX];
list<char> li;
vector<list<char>::iterator> ve;
vector<int> vee;
int getRes(int l,int r){
    int x=NIL,y=NIL,z=NIL;
    for(int i=l;i<=r;++i){
        if(cstr[i]=='(') vee.push_back(i);
        else{
            if(cstr[i]==')') vee.pop_back();
            else{
                if((cstr[i]=='+'||cstr[i]=='-')&&vee.empty()) x=i;
                else if((cstr[i]=='*'||cstr[i]=='/')&&vee.empty()) y=i;
                else if(cstr[i]=='^'&&vee.empty()) z=i;
            }
        }
    }
    if(x==NIL&&y==NIL&&z==NIL){
        if(cstr[l]=='(') return getRes(l+1,r-1);
        int res=0;
        for(int i=l;i<=r;++i)
            res=res*10+cstr[i]-'0';
        return res;
    }
    if(x!=NIL){
        if(cstr[l]=='-') return -getRes(l+1,r);
        else return cstr[x]=='+'?getRes(l,x-1)+getRes(x+1,r):getRes(l,x-1)-getRes(x+1,r);
    }
    if(y!=NIL) return cstr[y]=='*'?getRes(l,y-1)*getRes(y+1,r):getRes(l,y-1)/getRes(y+1,r);
    return pow((double)getRes(l,z-1),getRes(z+1,r));
}
int main(){
//  freopen(".in","r",stdin);
//  freopen(".out","w",stdout);
    int len=(scanf("%s",cstr+1),strlen(cstr+1));
    for(int i=1;i<=len;++i)
        li.push_back(cstr[i]);
    for(list<char>::iterator it=li.begin();it!=li.end();++it){
        if(*it=='(') ve.push_back(it);
        else if(*it==')'&&!ve.empty()) ve.pop_back();
    }
    for(int i=0;i<ve.size();++i)
        li.erase(ve[i]);
    copy(li.begin(),li.end(),cstr+1);
    len=li.size();
    printf("%d\n",getRes(1,len));
    return 0;
}

CH1802 表达式计算4的更多相关文章

  1. .NET平台开源项目速览(8)Expression Evaluator表达式计算组件使用

    在文章:这些.NET开源项目你知道吗?让.NET开源来得更加猛烈些吧!(第二辑)中,给大家初步介绍了一下Expression Evaluator验证组件.那里只是概述了一下,并没有对其使用和强大功能做 ...

  2. C# - 二叉树表达式计算

    很早以前就写过双栈的表达式计算. 这次因为想深入学一下二叉树,网上都是些老掉牙的关于二叉树的基本操作. 感觉如果就学那些概念,没意思也不好记忆.于是动手写了一个表达式计算的应用例子. 这样学习印象才深 ...

  3. C#动态表达式计算

    C#动态表达式计算 应该有不少人开发过程中遇到过这样的需求,我们直接看图说话: 如上图所示,其中Entity为实体类,其中包括五个属性,该五个属性的值分别来自于数据库查询结果: 用户通过可视化界面进行 ...

  4. C#动态表达式计算(续2)

    上两篇废话太多,这一次我就不多说了,由于代码比较简单,可以直接从https://github.com/scottshare/DynamicExpress.git地址下载. 以下说明一下使用方法: Dy ...

  5. 栈应用之 后缀表达式计算 (python 版)

    栈应用之 后缀表达式计算 (python 版) 后缀表达式特别适合计算机处理 1.  中缀表达式.前缀表达式.后缀表达式区别  中缀表达式:(3 - 5) * (6 + 17 * 4) / 3 17 ...

  6. C++实现 逆波兰表达式计算问题

    C++实现 逆波兰表达式计算问题 #include <iostream> #include <string> using namespace std; class Stack ...

  7. 算法笔记_044:表达式计算求值(Java)

    目录 1 问题描述 2 解决方案   1 问题描述 问题描述 输入一个只包含加减乖除和括号的合法表达式,求表达式的值.其中除表示整除. 输入格式 输入一行,包含一个表达式. 输出格式 输出这个表达式的 ...

  8. Fel表达式计算引擎学习

    转载原文地址:Fel是轻量级的高效的表达式计算引擎 Fel的问题 Fel的问题 Fel是轻量级的高效的表达式计算引擎 Fel在源自于企业项目,设计目标是为了满足不断变化的功能需求和性能需求. Fel是 ...

  9. 蓝桥杯 算法训练 ALGO-156 表达式计算

    算法训练 表达式计算   时间限制:1.0s   内存限制:256.0MB 问题描述 输入一个只包含加减乖除和括号的合法表达式,求表达式的值.其中除表示整除. 输入格式 输入一行,包含一个表达式. 输 ...

随机推荐

  1. 由angular命令行工具(angular-cli)生成的目录和文件

    e2e目录:是端到端的测试目录,包含基本的测试桩.是用来做自动测试的. src:应用源代码目录.我们写的所有代码都应该在这里面. app:包括应用的组件和模块.我们自己写的绝大部分代码都是写在这个目录 ...

  2. 《Think in Java》(十七)容器深入研究

    阿西吧,这一章好长啊,感觉看了快一个月了吧!JDK 自带的容器框架真是很好很强大啊,这一章看得有点蒙蒙的,接下来还得去看看官方文档啊!

  3. JQuery数字类型验证正则表达式

    有朋友整了一些关于js与jquery的数字类型验证正则表达式代码,下面我给大家再整理一下. 这里包括了数字验证实现与测试实例了,大家可参考. js验证数字正则表达式 代码如下: //检测是否为数字和小 ...

  4. JavaScript---事件监听

    JavaScript的事件监听是通过addEventListener()来实现的 它算是事件绑定的第二种方式. 他的特别之处在于这种绑定事件的方法不会被同名事件覆盖. 看具体的demo <!DO ...

  5. 通过一道面试题了解Condition线程通信

    Condition Condition接口描述了可能会与锁有关联的条件变量.这些变量在用法与使用Object.wait访问的隐式监视器类似,但提供了更强大的功能.需要特别指出的是,单个Lock可能与多 ...

  6. Java复习7.输入输出流

    Java复习7.输入输出流 20131005 前言: Java中涉及数据的读写,都是基于流的,这一块的知识相当重要,而且在Java中的数据,char字符是16bit的,所以存在字节流和字符流的区别.如 ...

  7. 老鼠走迷宫(2)输出所有路径(C语言)

    需求 有一个迷宫,在迷宫的某个出口放着一块奶酪.将一只老鼠由某个入口处放进去,它必须穿过迷宫,找到奶酪.请找出它的行走路径. STEP 1 题目转化 我们用一个二维数组来表示迷宫,用2表示迷宫的墙壁, ...

  8. zset类型以及其操作

    sorted set类型 sorted sets类型以及其操作zset是set的一格升级版本,它在set的基础上增加了一格顺序属性,这一属性在添加元素的同时可以指定,每次指定后,zset会自动重新按照 ...

  9. HashMap resize代码详解(二)

    关于其中的resize方法如下: final Node<K,V>[] resize() { Node<K,V>[] oldTab = table; int oldCap = ( ...

  10. dilworth定理+属性排序(木棍加工)

    P1233 木棍加工 题目描述 一堆木头棍子共有n根,每根棍子的长度和宽度都是已知的.棍子可以被一台机器一个接一个地加工.机器处理一根棍子之前需要准备时间.准备时间是这样定义的: 第一根棍子的准备时间 ...