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. 一次利用MSSQL的SA账户提权获取服务器权限

    遇到小人,把服务器整走了 自己手里只有sql server的sa账号密码 模糊记起之前用这个账户提权读取文件的事 百度之,发现相关信息一堆堆 各种工具也用了不少 发现不是语法错误就是权限不够 无奈之下 ...

  2. Android OpenGL ES 3.0 纹理应用

    本文主要演示OpenGL ES 3.0 纹理演示.接口大部分和2.0没什么区别,脚本稍微有了点变化而已. 扩展GLSurfaceView package com.example.gles300; im ...

  3. LENGTH和LENGTHB函数,substrb截取也是同一个道理。

    oracle 利用 LENGTH和LENGTHB函数区分中英文(2009-02-07 10:49:29) 转载▼ 标签: it 分类: oracle 前一段时间,我一朋友问我怎么得出这个字符串是中文还 ...

  4. iOS7初体验(1)——第一个应用程序HelloWorld

    iOS7 Beta已经发布了,迫不及待地下载了iOS 7及Xcode 5并体验了一下.先做一个简单的Hello World看看都有哪些变化吧. 1. 启动Xcode5-DP: 2. 从菜单选择File ...

  5. Javascript基础(2)

    开始更咯~~~嘻嘻. ---------------------------------------------------------------------------------- 异常捕获:即 ...

  6. Syntax error on token "package", assert expected------踩坑记录

    今天写程序碰到个坑,eclipse编辑,jdk1.7,clean编译项目后报错Syntax error on token "package", assert expected 反复 ...

  7. java问题整理

    1.一个“.java”源文件中是否可以包括多个类(不是内部类)?有什么限制? 答:可以有多个类.但只能有一个public类.并且public类名必须与文件名相一致.   2.Java有没有goto? ...

  8. PAT - 基础 - 最大公约数和最小公倍数

    题目: 本题要求两个给定正整数的最大公约数和最小公倍数. 输入格式: 输入在一行中给出2个正整数M和N(<=1000). 输出格式: 在一行中顺序输出M和N的最大公约数和最小公倍数,两数字间以1 ...

  9. Ubuntu14 或是其他系统当中关于sublimeSFTP超时解决方法

    一直都使用Sublime的SFTP功能,感觉还不错,好用,但是最近不知道怎么了,使用不成了,提示超时了,于是在网上找一下解决方法,没有找到,于是自己想着试试看,于在搞了一会,发现只要把配制文件当中的s ...

  10. C#【数据库】 Access类

    using System; using System.Data; using System.Data.OleDb; namespace AccessDb { /**//// <summary&g ...