豆豆的数学考试计算题
题目背景:
crxis是一个凶残的老师......
题目:
数学考试又到了,这次数学考试的计算题是由crxis出的,所以有点难。每道计算题都是一个只含“0”、“1”、“2”、“3”、“4”、“5”、“6”、“7”、“8”、“9”、“+”、“-”、 “*”、“/”、“^”、“(”、“)”的式子。然而,这对于还是宝宝的豆豆来说特别凶残,可是豆豆很想拿到分,于是他请求信息兼职数学巨大佬的你,帮忙编写一个计算算式的值的程序。豆豆每次都会输入一个不带等号的算式,请你输出这条算式的值。
样例:
输入样例:
2^(7*5-6*(8/2))
输出样例:
2048
样例解释:
原式=
个人题目:
豆豆的数学考试计算题
https://www.luogu.org/problem/U81547
题目分析 & 基本思想:
用栈模拟数字及数字操作符的后序遍历
代码:
//powered by Mr-Bean
#include<bots/stdc++.h>
using namespace std;
typedef long long int LL;//用LL替换long long int(方便定义)
LL i = 0, p = 1;//p储存栈的大小
LL number[10001];//模拟栈空间,储存数字
char symbol[10001];//模拟栈空间,储存数字操作符 ( + - * / ^ )
char s[456];//储存数字算术表达式
void push(void)//将一个数字操作符入栈
{
p++;
symbol[p] = s[i];
return;
}
void pop(void)//将一个数字操作符出栈,同时用数字栈顶及数字栈的第二个数字计算当前操作符
{
switch(symbol[p])//计算
{
case '+': number[p-1] += number[p]; break;
case '-': number[p-1] -= number[p]; break;
case '*': number[p-1] *= number[p]; break;
case '/': number[p-1] /= number[p]; break;
case '^': number[p-1] = pow(number[p-1], number[p]); break;
}
p = p - 1;
return;
}
int can(void)//判断是否开始计算一步
{
if((s[i]=='+' || s[i]=='-') && symbol[p]!='(')//如果上一个数字操作符是 + or - 则必须为 ( ) 才可以进行计算
{
return 1;
}
else if((s[i]=='*' || s[i]=='/') && (symbol[p]=='*' || symbol[p]=='/' || symbol[p]=='^'))//如果上一个数字操作符是 * or / 则必须为 * / ^ 才可以进行计算
{
return 1;
}
else//否则不可以进行计算
{
return 0;
}
}
int main()
{
int x;
scanf("%s", s);//输入数字算术表达式
s[strlen(s)] = ')';
symbol[p] = '(';
//给表达式套一个括号(方便加减计算的判断)
while(i < strlen(s))
{
while(s[i] == '(')
{
push();
i++;
}
x = 0;
while(s[i] >= '0' && s[i] <= '9')//转换成数字
{
x = x * 10 + s[i] - '0';
i++;
}
number[p] = x;
do
{
if(s[i] == ')')
{
while(symbol[p] != '(')
{
pop();
}
p--;
number[p] = number[p + 1];
}
else
{
while(can() == 1)
{
pop();
}
push();
}
i++;
}
while(i < strlen(s) && s[i - 1] == ')');
}
printf("%lld", number[0]);//答案就是栈顶数字
return 0;
}