题目
问题描述
输入一个只包含加减乖除和括号的合法表达式,求表达式的值。其中除表示整除。
输入格式
输入一行,包含一个表达式。
输出格式
输出这个表达式的值。
样例输入
1-2+3*(4-5)
样例输出
-4
数据规模和约定
表达式长度不超过100,表达式运算合法且运算过程都在int内进行。
思路
* 略略的有些low * 将字符串遍历一次,声明一个栈,存放左括号(
的位置,即遇到左括号(
就push一下这个括号的位置。遇到右括号)
就先得到与它对应的右括号(
的位置,即top(), 再pop()一下,准备下次的偶遇。自己写一个calculate函数,用于计算两个括号之间的表达式,然后将得到的结果用replace函数替换两个括号()
之间的表达式。这样遍历一遍之后,括号中的内容都已经计算出来了,并且没有括号了,再将表达式调用一遍calculate函数计算一遍即可得出正确的结果。
calculate函数思路
遍历一遍需要计算的字符串,判断其中的字符为*
还是\
,如果是,然后得到这个字符两边的数据,然后进行运算。
再遍历一遍需要计算的字符串,判断其中的字符为+
还是-
,如果是,然后得到这个字符两边的数据,然后进行运算。
需要注意的几点
- 使用replace函数后记得将循环变量设置为被替换的的字符串中的
(
的位置,循环的下次需要从那里开始。 - calculate函数取运算符两边的值的时候,需要注意可能是个负数,负数是有个
-
号的。 - 这个代码中使用了 * c++11才支持的to_string函数 * ,这个函数可以把整数转换为字符串。蓝桥杯会出现编译错误,自己去写个吧。我就不写了。
- * 还有最重要的一点,博主很cool !�� *
代码
#include <iostream>
#include "string"
#include "stack"
#include "math.h"
using namespace std;
string operate(int a1, int a2, char oper) {
int result=0;
if (oper=='+') {
result=a1+a2;
} else if (oper=='-') {
result=a1-a2;
} else if (oper=='*') {
result=a1*a2;
} else if (oper=='/') {
result=a1/a2;
}
return std::to_string(result);
}
string calculate(string str) {
int p, q;
for (int i=0; i<=str.length(); i++) { // 这个循环用来计算乘除法
if (str[i]=='*' || str[i]=='/') {
int rightNum=0;
int leftNum=0;
bool isNeg=false;
for (p=i+1; p<str.length(); p++) {
if (str[i+1]=='-'&&p==i+1) {
isNeg=true;
continue;
}
int d=str[p]-'0';
if (0<=d && d<=9) {
rightNum=rightNum*10+d;
} else {
break;
}
}
if (isNeg) {
rightNum=-rightNum;
}
for (q=i-1; q>=0; q--) {
int d=str[q]-'0';
if (0<=d && d<=9) {
leftNum=leftNum+d*pow(10, i-q-1);
} else {
if(str[q]=='-'&&str[q]-'0'>=0) {
leftNum=-leftNum;
q--;
}
break;
}
}
string temp=operate(leftNum, rightNum, str[i]);
str=str.replace(q+1, p-1-q, temp);
i=q+1;
}
}
for (int i=0; i<=str.length(); i++) { // 这个循环用来计算加减法
if (str[i]=='+' || str[i]=='-') {
int rightNum=0;
int leftNum=0;
bool isNeg=false;
for (p=i+1; p<str.length(); p++) {
if (str[i+1]=='-'&&p==i+1) {
isNeg=true;
continue;
}
int d=str[p]-'0';
if (0<=d && d<=9) {
rightNum=rightNum*10+d;
} else {
break;
}
}
if (isNeg) {
rightNum=-rightNum;
}
for (q=i-1; q>=0; q--) {
int d=str[q]-'0';
if (0<=d && d<=9) {
leftNum=leftNum+d*pow(10, i-q-1);
} else {
if(str[q]=='-'&&str[q-1]-'0'<0) {
leftNum=-leftNum;
q--;
}
break;
}
}
string temp=operate(leftNum, rightNum, str[i]);
str=str.replace(q+1, p-1-q, temp);
i=q+1;
}
}
return str;
}
int main(int argc, const char * argv[]) {
// insert code here...
stack<int> leftStk;
string inStr;
string subStr;
int left=0;
cin>>inStr;
for (int i=0; i<inStr.length(); i++) {
if (inStr[i]=='(') {
leftStk.push(i);
} else if (inStr[i]==')') {
left=leftStk.top();
leftStk.pop();
subStr=inStr.substr(left+1, i-left-1);
inStr.replace(left, i-left+1, calculate(subStr));
i=left;
}
}
cout<<calculate(inStr)<<endl;
return 0;
}
//(1+2)*(3+4)+4*(5+4)*6/7