<题目链接>

<转载于 >>>  >

题目大意:

给你n个数,和一个最终的结果,再给你一个含有n个不同变量的式子,问你这个式子最终能否得到指定的答案。

解题分析:
我们可以利用全排列给这n个变量分配对应的值,然后就是对给定的式子进行表达式求值了。

对给定式子进行表达式求值有两种方法:

一、将中缀表达式转化为后缀表达式,然后对后缀表达式进行计算

(1)、把中缀表达式转换为后缀表达式算法的基本思路是从头到尾地扫描中缀表达式中的每个字符,对于不同类型的字符按不情况进行处理。
1、先定义一个工作数组,用来存储转换之后的后缀表达式,定义一个栈,用来存储运算符。(越往栈顶优先级越高的原则)可以先定义一个‘#’优先级为0存入栈底
2、扫描:若遇到的是操作数,直接存入工作数组中,若遇到运算符,将该运算符与栈顶元素比较,若该运算符优先级高,直接入栈,否则,
   弹栈,直到栈顶元素优先级比该运算符优先级低,出栈后的运算符存入工作数组里。‘(’进栈时要定义低优先级,出现‘)’则弹栈。
3、扫描到中缀表达式结束符'\0'时,把栈中剩余的运算符弹出存入工作数组中。

(2)、计算后缀表达式的思路是:
1、从左向右扫描后缀表达式,遇到运算符就把栈顶两个元素出栈,执行运算,得到的结果再入栈.
例:(a+b)*c的逆波兰式为ab+c*,假设计算机把ab+c*按从左到右的顺序压入栈中,并且按照遇到运算符就把栈顶两个元素出栈,执行运算,
得到的结果再入栈的原则来进行处理,那么ab+c*的执行结果如下:
  1)a入栈(0位置)
  2)b入栈(1位置)
  3)遇到运算符"+",将a和b出栈,执行a+b的操作,得到结果d=a+b,再将d入栈(0位置)
  4)c入栈(1位置)
  5)遇到运算符"*",将d和c出栈,执行d*c的操作,得到结果e,再将e入栈(0位置)

二、直接计算中缀表达式思路:
1、定义两个栈,一个用来存取运算符,一个用来存取操作数。
2、从左向右扫描表达式,遇到操作数,直接存入操作数栈中,遇到运算符,将该运算符与运算符栈顶元素比较,若该运算符优先级高,直接入栈,否则弹栈,同时取操作数栈的最上面两个元素和弹出的运算符进行运算,结果压入操作数栈中。直到运算符栈顶元素优先级比该运算符
优先级低。
3、扫描完毕后,运算符依次出栈。注意:只要有一个运算符出栈,就要去操作数栈中的最上面两个元素进行计算,并把结果压入操作数栈中。

 #include <iostream>
 #include <cstdio>
 #include <algorithm>
 #include <cstring>
 #include <string>
 #include <stack>
 #include <map>
 using namespace std;
  + ;
 map<char, int> mpa;

 string change(string str) {
     string ans;
     stack<char> s;
     map<char, int> op;
     op[; op[;   //给这些符号分配优先级
     op[; op[;
     op[;
     s.push('#');
     ; i < str.size(); ++i) {
         if(str[i] >= 'a' && str[i] <= 'z') ans += str[i];
         else {
             if(str[i] == ')') {
                 do {
                     ans += s.top();
                     s.pop();
                 } while(s.top() != '(');
                 s.pop();  // 弹出(
             }
             else if(op[str[i]] > op[s.top()])    //如果当前符合优先级大于栈顶,则入栈
                 s.push(str[i]);
             else {
                 do {
                     if(s.top() == '(') break;
                     ans += s.top();
                     s.pop();
                 } while(op[s.top()] >= op[str[i]]);
                 s.push(str[i]);
             }
         }
     }
     while(s.top() != '#') {
         ans += s.top();
         s.pop();
     }
     return ans;
 }

 int slove(string str) {
     stack<int> s;
     ; i < str.size(); ++i) {
         if(str[i] >= 'a' && str[i] <= 'z') s.push(mpa[str[i]]);
         else {
             int a, b;
             b = s.top(); s.pop();
             a = s.top(); s.pop();
             if(str[i] == '+') s.push(a + b);
             else if(str[i] == '-') s.push(a - b);
             else if(str[i] == '*') s.push(a * b);
         }
     }
     return s.top();
 }

 int n, k;
 int a[maxn];
 string ss;

 int main() {
     while(scanf("%d", &n) != EOF && n) {
         ; i < n; ++i)
             scanf("%d", &a[i]);
         scanf("%d", &k);
         cin >> ss;
         sort(a, a + n);   //因为下面要进行全排列,所以这里要排序
         string res = change(ss);  //得到转换后的后缀表达式
         bool ok = false;
         do {
             ;
             ; i < ss.size(); ++i)
                 if(ss[i] >= 'a' && ss[i] <= 'z') mpa[ss[i]] = a[r++];  //给每个变量分配实际数据
             int ans = slove(res);   //根据分配的数据算出结果
             if(ans == k) {
                 ok = true;
                 break;
             }
         } while(next_permutation(a, a + n));     //对a进行全排列,得到所有变量的分配情况
         if(ok) printf("YES\n");
         else printf("NO\n");
     }
     ;
 }

2018-10-05

hdu 4192 (表达式求值)的更多相关文章

  1. 随手练——HDU 1237 表达式求值(输入格式典型)

    坑了老子半天,结果是 float 范围不够!!! 基本思想: 开一个符号栈,一个数字栈: 碰到数字就入栈,碰到符号就与栈顶符号进行对比,如果当前符号优先级小于栈顶符号,数字栈弹出两个数进行栈顶符号运算 ...

  2. Polynomial Problem(hdu 1296 表达式求值)

    We have learned how to obtain the value of a polynomial when we were a middle school student. If f(x ...

  3. hdu 1237 简单计算器 (表达式求值)【stack】

    <题目链接> 题目大意: 读入一个只包含 +, -, *, / 的非负整数计算表达式,计算该表达式的值.  Input测试输入包含若干测试用例,每个测试用例占一行,每行不超过200个字符, ...

  4. Matrix Chain Multiplication(表达式求值用栈操作)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1082 Matrix Chain Multiplication Time Limit: 2000/100 ...

  5. 表达式求值(noip2015等价表达式)

    题目大意 给一个含字母a的表达式,求n个选项中表达式跟一开始那个等价的有哪些 做法 模拟一个多项式显然难以实现那么我们高兴的找一些素数代入表达式,再随便找一个素数做模表达式求值优先级表 - ( ) + ...

  6. 用Python3实现表达式求值

    一.题目描述 请用 python3 编写一个计算器的控制台程序,支持加减乘除.乘方.括号.小数点,运算符优先级为括号>乘方>乘除>加减,同级别运算按照从左向右的顺序计算. 二.输入描 ...

  7. 数据结构算法C语言实现(八)--- 3.2栈的应用举例:迷宫求解与表达式求值

    一.简介 迷宫求解:类似图的DFS.具体的算法思路可以参考书上的50.51页,不过书上只说了粗略的算法,实现起来还是有很多细节需要注意.大多数只是给了个抽象的名字,甚至参数类型,返回值也没说的很清楚, ...

  8. nyoj305_表达式求值

    表达式求值 时间限制:3000 ms  |  内存限制:65535 KB 难度:3   描述 Dr.Kong设计的机器人卡多掌握了加减法运算以后,最近又学会了一些简单的函数求值,比如,它知道函数min ...

  9. 利用栈实现算术表达式求值(Java语言描述)

    利用栈实现算术表达式求值(Java语言描述) 算术表达式求值是栈的典型应用,自己写栈,实现Java栈算术表达式求值,涉及栈,编译原理方面的知识.声明:部分代码参考自茫茫大海的专栏. 链栈的实现: pa ...

随机推荐

  1. Confluence 6 通过 SSL 或 HTTPS 运行 - 备注和问题解决

    备注 在创建证书时候的背景信息: 'keytool -genkeypair' 命令将会创建秘钥对,包括公钥和关联的私钥,然后存储到  keystore 中.这个命令打包公钥为  X.509 v3 自签 ...

  2. Confluence 6 升级自定义的站点和空间获得你的自定义布局

    我们建议你在对站点进行布局修改的时候,你需要为你修改的 Confluence 站点或空间布局保留所有的修改记录. 如果没有的话,你应该可以通过下面的办法找到你的自定义修改.这个方法将会把你对全部网站和 ...

  3. ES6学习路上的小学生,promise处理异步操作,简易原始起步之用。先能用,再深究!

    ES6的promise对象,让我们更容易的处理这样的需求:执行完一个方法以后,再去执行下一个方法. 理解尚浅之时,先用于项目之中. var promise1 = new Promise(functio ...

  4. 如何在PDF中添加水印,PDF添加水印技巧

    PDF文件现在的使用很是普遍,不管是工作中还是学习中都会使用到PDF文件,制作一个PDF文件就很辛苦的,我们要是想把PDF文件中添加水印防止抄袭的时候应该要怎么做呢,其实吧PDF文件添加水印还挺简单的 ...

  5. C#概念总结(五)

    1.C#特性 (Attribute) 特性适用于在运行时传递程序中的各中元素(比如 类.方法.结构.枚举.组件)的行为信息额声明性标签,可以通过使用特性向程序添加声明性信息,一个声明标签是通过放置在他 ...

  6. 小学生都看得懂的C语言入门(2): 判别 循环的一些应用实例

    1.bool 类型 定义bool类型之前需要导入#include <stdbool.h> #include <stdio.h> #include <stdbool.h&g ...

  7. Nginx详解七:Nginx基础篇之Nginx官方模块

    Nginx官方模块 --with-http_stub_status_module:Nginx的客户端状态,用于监控连接的信息,配置语法如下:配置语法:stub_status;默认状态:-配置方法:se ...

  8. Java+selenium之WebDriver常见特殊情况如iframe/弹窗处理(四)

    1. iframe 的处理 查找元素必须在对应的 ifarme 中查找,否则是找不到的 // 传入参数为 frame 的序号,从0开始 driver.switchTo().frame(Int inde ...

  9. 数据库和linux对大小写的区分

  10. Django_Admin操作

    Django_Admin 创建Django_Admin 管理账户 D:\github\Django_Aadmin>python manage.py createsuperuser Usernam ...