The #A1356 计算(calc) is so difficult and challenging.

Let ChaYe teach you.

只要把这道题看成一局游戏就可以快乐做题了

I. 顶以遍亮起手,以防被报错吃伤害

Tip:
建议定义全局变量,可以自动初始化,不用担心之后进行类似“a++”等操作时出问题

stack <int> number; // 数字栈
stack <char> symbol; // 符号栈

string str; // 输入内容
int len, num; // 输入内容长度以及要入数字栈的数
bool flag = false; // 是否要将 要入数字栈的数 入栈

II. 度踢,以防程序写好之后题目偷家

提炼有用信息:

1. “ 方程中只有(’,‘)’,‘09’,‘+’,‘’,‘’,‘/’,‘(’,‘)’,‘0-9’,‘+’,‘-’,‘*’,‘/’,‘^’

很多人会被这一句话和样例误解,以为是只有一位数,最后惨遭题目偷家,但其实是有多位数的

2.破密了Ferrari设的密码门

Ferrari(music)

(music)I'm a Ferrari~~

(music)pulled off on Mulholland Drive~~

(music)Over the city, the lights are so pretty from up here~~~~~~

III. 想算法写代码,疯狂书写战斗爽!

根据题意+样例,我们得知输入为 中缀表达式

所以我们有一下三种解题方式:

1.中缀转前缀后计算

2.中缀转后缀后计算

3.莽一手,直接计算

因为茶叶的脑容量不够,想不到怎么转,所以我选择

莽一手,直接计算


Tip: 因为输入没有空格,所以我们选择使用stringstring类型输入,在输入后进行遍历操作


1 首先解决数字的入栈

因为数字是多位数,所以我们选择使用一个intint类型变量numnum用来存储要入数字栈的数

当当前字符为数字字符时,将numnum的个位窜到百位,百位窜到千位,以此类推,使用num *= 10就可以轻松实现

当到达符号字符时说明数字已经结束,这个时候就可以将numnum入栈数字栈

但怎么知道有数字要入栈呢?

可以定义一个用来判断要不要将变量numnum入栈的boolbool变量:flagflag,在num *= 10的时候将flagflag设为truetrue,在入栈后将flagflag设为falsefalse。这样一来,在到达符号字符时通过判断flagflag的值就可以知道该不该入栈了

2 开始BOSS战:符号字符怎么办?

a. 特殊情况!是'('!

当当先遍历到的符号字符为 '(' 时,该怎么办呢? 还能怎么办?小小左括号,不足挂齿,直接扔进符号栈就好了

b. 特殊情况again!是')'!

当当先遍历到的符号字符为 ')' 时就需要警惕起来了!

上过小学的都知道,括号里的运算等级更高,所以我们需要在遇到 ')' 时马上计算括号内内容!,只要没有到达 '(' 就一直计算,这个时候就体现出把 '(' push到符号栈里的作用了,用来计算括号内内容

但怎么计算呢?

这个题目在这一步还是比较友善,因为所有的运算都需要两个数参与

所以我们可以先取到数字栈栈顶的两个数和符号栈栈顶的符号进行运算,运算过程直接判断符号运算就好

如何取栈顶示例:

int b = number.top(); // 取栈顶
number.pop(); // 出栈顶,这里出栈顶正好对应了我们要实现的计算完成后弹出符号/数字

因为计算需要反复使用,所以建议打包成函数方便以后使用


Tip:

注意注意注意数字栈栈顶两数的顺序!!!

栈:先入后出,后入先出

stack: first in last out, last in, first out

Tip2: 计算完括号内内容需要将符号栈栈顶出栈,因为此时的栈顶是 '(' ,如果留着会出大问题……


c. easy小怪,直接KO 理清逻辑!!

不要觉得普通是普通符号字符就可以直接进入符号栈,如果你是这样想的,那你是这个

 ..........、
 .........../|
 .........../|
 .........../|
 .........
     ...
     ...

因为我们的数学还有优先级这个类似战力值的概念,所以我们需要先把战力值比当前符号字符高的符号计算完才能让它入栈

这里就到了茶叶坐牢的点!

首先我们需要知道当前符号字符的战力值栈顶符号的战力值

怎么知道呢?题目又没有给出……

答曰:自定义。

我们根据小学数学知识定下如下规则:

BEST level: 战力值为 3030 为最高级,是 ^(阶乘)

MIDDLE level: 战力值为 2020 为中间级,是 *//

WORST level: 战力值为 1010 为最拉级,是 ++-

现在就可以通过战力值(优先级)来评定谁强谁拉了

因为要重复使用,建议定义为一个求战力值函数 (头铁不用函数硬写也不是不可以)

怎么真正实施计算呢?

直接调用已经写好的计算函数啊!

计算战力值比当前符号字符高的强者拢共分三↑步

① 比较战力值!打不过赶紧跑

只要调用写好的求战力值函数就可以获得符号栈栈顶符号的战斗力与当前符号字符的战斗力,获得之后作比较就好力


Tip: 记得用whilewhile,因为可能不止一个符号的战斗力比当前符号的高


② 预防 returnreturn valuevalue 32212254773221225477 绕后偷家破你防吃你兵线直接KO你最后还要舔你包把你搜刮的什么都不剩

※※※※重要※※※※

※※※※因为我们的计算函数中绝对会使用栈名.pop(),所以必须在外围的whilewhile循环中加入条件:!symbol.empty()※※※※

巧妙的是数字栈并不用担心这一点,因为从题意就可以得出数字的个数绝对比符号的个数多,所以只要符号还有东西就一定有数字参加运算给你pop

这个时候没有脑子不会思考的人就会问了:“茶叶茶叶,如果全是括号那数字不就比符号少了”,但是我们前面已经筛掉了是括号的可能

③ 为什么茶叶要写这个呢?

冲去小卖部马上购买东方树叶青柑普洱喝一口


BIG IMPORTANT TIP: 在运算完战力值比当前符号更高的符号后请记得

将当前符号入栈符号栈

(叒只茶叶就因为这个小细节卡了一会)


d. 优雅结尾,华丽收场

因为可能有些刁钻的测试样例会在所有运算结束后留下数字

所以需要在最后判断一下flagflag变量(还记得是什么吗?不记得建议重看一遍),如果flagflag变量为truetrue,说明还有数残留,所以要把numnum入栈数字栈

因为刚刚可能有数字残留,但数字是要用来计算的,计算又是成双成对的,所以我们需要重新计算一下,但是并没有上面那么复杂,只要while(!symbol.empty())就好了,如果达成条件就调用计算函数就好了

最后输出number.top(),因为计算函数会将计算的值入栈数字栈,所以在最结尾时,number.top()就是结果

~MVP结算~

总体结算:自己理清思路后把所有写上就能AC这一局

打法分析:只要不被上“思路混沌”debuff,保持思路清晰就可以easily AC

想要代码可以找茶叶,但是茶叶可能不会给