Description

A math instructor is too lazy to grade a question in the exam papers in which students are supposed to produce a complicated formula for the question asked. Students may write correct answers in different forms which makes grading very hard. So, the instructor needs help from computer programmers and you can help.

You are to write a program to read different formulas and determine whether or not they are arithmetically equivalent.

Input

The first line of the input contains an integer N (1 <= N <= 20)
that is the number of test cases. Following the first line, there are
two lines for each test case. A test case consists of two arithmetic
expressions, each on a separate line with at most 80 characters. There
is no blank line in the input. An expression contains one or more of the
following:

  • Single letter variables (case insensitive).
  • Single digit numbers.
  • Matched left and right parentheses.
  • Binary operators +, - and * which are used for addition, subtraction and multiplication respectively.
  • Arbitrary number of blank or tab characters between above tokens.

Note:
Expressions are syntactically correct and evaluated from left to right
with equal precedence (priority) for all operators. The coefficients and
exponents of the variables are guaranteed to fit in 16-bit integers.

Output

Your program must produce one line for each test case. If input
expressions for each test data are arithmetically equivalent, "YES",
otherwise "NO" must be printed as the output of the program. Output
should be all in upper-case characters.

Sample Input

3
(a+b-c)*2
(a+a)+(b*2)-(3*c)+c
a*2-(a+c)+((a+c+e)*2)
3*a+c+(2*e)
(a-b)*(a-b)
(a*a)-(2*a*b)-(b*b)

Sample Output

YES
YES
NO

解题思路:我的程序是把每个 'a'--'z' 的字母分别hash成0--25             再把每个 'A'--'Z' 的字母分别hash成0--25

大概题意:
给出两个数学式子判断其结果是否相等。
解法:
1,用栈将表达式转换成为后缀式,然后计算后缀表达式的只判断其是否相等。
2,其中有一个问题就是字母转换之后如何算其值来代表其字母的值,我用的是(int)s1[i]直接将其ASCII作为数值对待,结果也AC了(看来这个
题只是判断两个表达式是否在数值上是等价的而不是判断两个公式是否等价 比如说:(b-a+c)*2 与
(1+c)*2也相等,但是如果作为公式的话这两个是不相等的)。
下面说一下中缀表达式转后缀表达式

规则

中缀表达式a + b*c + (d * e + f) * g,其转换成后缀表达式则为a b c * + d e * f  + g * +。

转换过程需要用到栈,具体过程如下:

1)如果遇到操作数,我们就直接将其输出。

2)如果遇到左括号,我们直接将其放入到栈中。

3)如果遇到一个右括号,则将栈元素弹出,将弹出的操作符输出直到遇到左括号为止。注意,左括号只弹出并不输出。

4)如果遇到任何其他的操作符,如(“+”, “*”,“-“)等,从栈中弹出元素直到遇到发现更低优先级的元素(或者栈为空)为止。弹出完这些元素后,才将遇到的操作符压入到栈中。有一点需要注意,只有在遇到" ) "的情况下我们才弹出" ( ",其他情况我们都不会弹出" ( "。优先级从大到小顺序为:" * " 与 " / "," + " 与 " - ","(",也就是说"
( "优先级最低。

5)如果我们读到了输入的末尾,则将栈中所有元素依次弹出。

规则

规则很多,还是用实例比较容易说清楚整个过程。以上面的转换为例,输入为a + b * c + (d * e + f)*g,处理过程如下:

1)首先读到a,直接输出。

2)读到“+”,将其放入到栈中。

3)读到b,直接输出。

此时栈和输出的情况如下:

4)读到“*”,因为栈顶元素"+"优先级比" * " 低,所以将" * "直接压入栈中。

5)读到c,直接输出。

此时栈和输出情况如下:

6)读到" + ",因为栈顶元素" * "的优先级比它高,所以弹出" * "并输出, 同理,栈中下一个元素" + "优先级与读到的操作符" + "一样,所以也要弹出并输出。然后再将读到的" + "压入栈中。

此时栈和输出情况如下:

7)下一个读到的为"(",所以直接放入到栈中。

8)读到d,将其直接输出。

此时栈和输出情况如下:

9)读到" * ",由于只有”(“的优先级最低,遇到" ) "的时候左括号"("才会弹出,所以" * "压入栈中。

10)读到e,直接输出。

此时栈和输出情况如下:

11)读到" + ",弹出" * "并输出,然后将"+"压入栈中。

12)读到f,直接输出。

此时栈和输出情况:

13)接下来读到“)”,则直接将栈中元素弹出并输出直到遇到"("为止。这里右括号前只有一个操作符"+"被弹出并输出。

14)读到" * ",压入栈中。读到g,直接输出。

15)此时输入数据已经读到末尾,栈中还有两个操作符“*”和" + ",直接弹出并输出。

至此整个转换过程完成。程序实现代码后续再补充了。

然后是后缀表达式求值

后缀表达式也叫逆波兰表达式,其求值过程可以用到栈来辅助存储。假定待求值的后缀表达式为:6  5  2  3  + 8 * + 3  +  *,则其求值过程如下:

1)遍历表达式,遇到的数字首先放入栈中,此时栈如下所示:

2)接着读到“+”,则弹出3和2,执行3+2,计算结果等于5,并将5压入到栈中。

3)读到8,将其直接放入栈中。

4)读到“*”,弹出8和5,执行8*5,并将结果40压入栈中。而后过程类似,读到“+”,将40和5弹出,将40+5的结果45压入栈...以此类推。最后求的值288。

借鉴了高人的解题思路,自己不怎么表达的清楚

程序代码:

#include<iostream>
#include <cstdio>
#include<cstring>
#define N 100
using namespace std;
int calculate(char s[],int t,int n) //计算
{
if(n<t) return ;
if(n==t)
{
if(s[t]>='A' && s[t]<='Z') return (s[t]-'A');
else
if(s[t]>='a' && s[t]<='z') return (s[t]-'a');
else return s[t]-'';
}
int f1=-,f2=-; //f1 : '+' 或者是 '-'的位子;f2 : '*'的位子
int kuohao=;
for(int i=t;i<=n;i++)
{
if(s[i]=='(') kuohao++;
else
if(s[i]==')') kuohao--;
else
if((s[i]=='+' || s[i]=='-') && kuohao==) f1=i;
else
if(s[i]=='*' && kuohao==) f2=i;
}
if(f1< && f2<) return calculate(s,t+,n-);
if(f1>)
{
if(s[f1]=='+') return calculate(s,t,f1-)+calculate(s,f1+,n);
else return calculate(s,t,f1-)-calculate(s,f1+,n);
}
else return calculate(s,t,f2-)*calculate(s,f2+,n);
}
void g(char s[])
{ char *p=s;
char temp[N],*p1=temp; while(*p!='\0')
{
while(((*p==' ') ||(*p=='\t')) && (*p!='\0')) *p++;
*p1=*p;
p1++;
p++;
}
*p1='\0';
strcpy(s,temp);
}
int main()
{
int t;
scanf("%d",&t);getchar();
while(t--)
{
char str1[N],str2[N];
gets(str1);
gets(str2);
g(str1);
g(str2);
int a=calculate(str1,,strlen(str1)-);
int b=calculate(str2,,strlen(str2)-);
if(a==b)cout<<"YES\n";
else cout<<"NO\n";
}
return ;
}

数据结构——POJ 1686 Lazy Math Instructor 栈的应用的更多相关文章

  1. POJ 1686 Lazy Math Instructor(栈)

    原题目网址:http://poj.org/problem?id=1686 题目中文翻译: Description 数学教师懒得在考卷中给一个问题评分,因为这个问题中,学生会为所问的问题提出一个复杂的公 ...

  2. POJ 1686 Lazy Math Instructor (模似题+栈的运用) 各种坑

    Problem Description A math instructor is too lazy to grade a question in the exam papers in which st ...

  3. poj 1684 Lazy Math Instructor(字符串)

    题目链接:http://poj.org/problem?id=1686 思路分析:该问题为表达式求值问题,对于字母使用浮点数替换即可,因为输入中的数字只能是单个digit. 代码如下: #includ ...

  4. Lazy Math Instructor

      Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 3721   Accepted: 1290 Description A m ...

  5. UVALive 2056 Lazy Math Instructor(递归处理嵌套括号)

    因为这个题目说明了优先级的规定,所以可以从左到右直接运算,在处理嵌套括号的时候,可以使用递归的方法,给定每一个括号的左右边界,伪代码如下: int Cal(){ if(括号)  sum += Cal( ...

  6. POJ - 2183 Bovine Math Geniuses

    “模拟“题,运用哈希,不断地按照一定运算规律对一个结果进行计算,如果重复出现就停止并且输出该数.注意到仔细看题,这种题一定要细心! POJ - 2183 Bovine Math Geniuses Ti ...

  7. 数据结构--线段树--lazy延迟操作

    A Simple Problem with Integers Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 53749   ...

  8. 数据结构录 之 单调队列&单调栈。

    队列和栈是很常见的应用,大部分算法中都能见到他们的影子. 而单纯的队列和栈经常不能满足需求,所以需要一些很神奇的队列和栈的扩展. 其中最出名的应该是优先队列吧我觉得,然后还有两种比较小众的扩展就是单调 ...

  9. 数据结构录 之 单调队列&单调栈。(转)

    http://www.cnblogs.com/whywhy/p/5066306.html 队列和栈是很常见的应用,大部分算法中都能见到他们的影子. 而单纯的队列和栈经常不能满足需求,所以需要一些很神奇 ...

随机推荐

  1. JS根据key值获取URL中的参数值,以及把URL的参数转换成json对象

    //把url的参数部分转化成json对象 parseQueryString: function (url) { var reg_url = /^[^\?]+\?([\w\W]+)$/, reg_par ...

  2. Axiom3D学习日记 0.Axiom基础知识

    Axiom 3D Engine An open-source, cross-platform, managed 3D rendering engine for DirectX, XNA and Ope ...

  3. JAVA HashMap详细介绍和示例

    http://www.jb51.net/article/42769.htm 我们先对HashMap有个整体认识,然后再学习它的源码,最后再通过实例来学会使用HashMap.   第1部分 HashMa ...

  4. Array,ArrayList 和 List<T>的选择和性能比较.

    Array Class Provides methods for creating, manipulating, searching, and sorting arrays, thereby serv ...

  5. oracle 查看用户表数目,表大小,视图数目等

    查看当前用户的缺省表空间 SQL>select username,default_tablespace from user_users; 查看当前用户的角色 SQL>select * fr ...

  6. tomcat的webapp下的root文件夹的作用是什么

    1.基本一样..只是表示不同的tomcat的http路径而已. root目录默认放的是tomcat自己的一个项目,如:http://localhost:8080/默认访问root项目 对于webapp ...

  7. photoshop中rgb与索引模式的区别

    RGB: 是色域最宽广的颜色模式它是一种光色模式不难理解  你的显示器 就是根据这个模式来显示图像的同样 我们在自然界中 看到的所有五颜六色的东西都是吸收了不同颜色的光 而得到的所以这一颜色模式 与我 ...

  8. C宏系统缺陷

    这两天稍稍看了一下boost的preprocessor库,发觉boost那帮疯子竟然利用各种奇技淫巧定义出各种数据类型和结构,还在上面定义出加减乘除等等各种运算,在快速浏览的过程中,还瞄到了很眼熟的各 ...

  9. 干掉Google字体,WordPress速度暴涨

    2014年7月7日23:40:31 因为Google被墙,WordPress引用的Google字体总会加载很长时间,严重影响打开速度. 安装WordPress插件 Disable Google Fon ...

  10. dictionary(字典)

    dictionary(字典):   字典对象   字典是一种key - value 的数据类型,使用就像我们上学用的字典,通过笔划.字母来查对应页的详细内容. 1.      dic={"n ...