<题目链接>

<转载于 >>>  >

题目大意:

给你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. ionic3 国际化

    http://www.cnblogs.com/huangenai/p/6868173.html 按上面这个网站的步骤整一遍, 但是ionic3 会报错  所以 在 import { NgModule ...

  2. 好用的JS拖拽插件

    下载artDialog插件的时候发现它把拖拽单独封装成了一个方法,挺好用的,使用方法如下... 第一种拖拽方式-点击容器指定区域进行拖拽 $('.ui-dialog').on(DragEvent.ty ...

  3. 【linux】Linux误删C基本运行库libc.so.6急救方法

    转自:http://www.cnblogs.com/fjping0606/p/4551475.html 下面全文都是拷贝的上面链接的内容. 首先普及一下关于libc.so.6的基本常识: libc.s ...

  4. Metasploit框架问题

    1.使用nmap 扫描SMB服务漏洞信息 nmap -P0 --script=smb-check-vulns 10.10.15.123 2.sql语句绕过后台 这部分我待会补充 只有尽可能的过滤,没有 ...

  5. lightoj1214 大数取模模板

    #include<bits/stdc++.h> using namespace std; #define maxn 300 #define ll long long ll a,b; ]; ...

  6. IP的计算

    IP的计算 时间限制: 1 Sec  内存限制: 32 MB 位无符号整数来表示,一般用点分方式来显示,点将IP地址分成4个部分,每个部分为8位,表示成一个无符号整数(因此不需要用正号出现),如192 ...

  7. Nginx详解二十八:Nginx架构篇Nginx+Lua的安全waf防火墙

    Nginx+Lua的安全waf防火墙 看一下别人写好的:https://github.com/loveshell/ngx_lua_waf 先安装git:yum -y install git 在/opt ...

  8. 在vue项目中使用axios发送FormData

    这个是axios的中文文档,挺详细的: https://www.kancloud.cn/luponu/axios/873153 文档中的    使用 application/x-www-form-ur ...

  9. linux下的抓包

    1. 查看网卡名字 cat /proc/net/dev 2.抓取外网进来的包 tcpdump -i eth0 port -s -w .pcap 3.抓取自己服务器上的两个程序之间访问的数据 换成 lo ...

  10. 微信公众号开发调用自带地图 不显示(openLocation)

    1.需要在wx.config中声明需要使用的功能(openLocation) 例如: wx.config({ debug: false, // 开启调试模式,调用的所有api的返回值会在客户端aler ...