题目描述:
输入一个表达式(用字符串表示),求这个表达式的值。
保证字符串中的有效字符包括[‘0’-‘9’],‘+’,‘-’, ‘*’,‘/’ ,‘(’, ‘)’,‘[’, ‘]’,‘{’ ,‘}’。且表达式一定合法。
输入描述:
输入一个算术表达式
输出描述:
得到计算结果
示例:
输入:
3+2*{1+2*[-4/(8-6)+7]}
输出:
25
解题思路:
这道题如果用Python做挺简单的,但是用C++没有现成的函数调用,只能自己来写四则运算函数了。Calculation函数完成四则运算,其逻辑大致如下:
首先判断式子两端是否有括号,若正好两侧有,则前后缩进,计算内部公式;再判断内部公式中最后出现的计算符(加减和乘除)位置,若有加减则先算加减,然后分别将计算符前后的内容用Calculation计算,依次递归;直到某一层内容不存在计算符,即只有数字内容,用stoi函数将其转换为整型,进行计算,完成。
注意,在上述逻辑中有一个flag,它的意义在于判断是否有多层括号,比如公式为((5+3)),其内部式子为(5+3),在分析其内容时,因为两侧有括号包围,所以am和md都为0,此时如果直接用stoi就会失效,那么就将start和end往里缩进一层,调用Calculation,这样就实现了多层括号的识别。
测试代码:
#include <string> #include <vector> #include <iostream> using namespace std; int Calculation(string& exp, int start, int end) { // 判断是否有括号,若两端包围则计算内部 if ((exp[start] == '(' || exp[start] == '[' || exp[start] == '{') && (exp[end-1] == ')' || exp[end-1] == ']' || exp[end-1] == '}')) { vector<int> vec; for (int i = start; i < end-1; ++i) { if (exp[i] == '(' || exp[i] == '[' || exp[i] == '{') vec.push_back(i); else if (exp[i] == ')' || exp[i] == ']' || exp[i] == '}') vec.pop_back(); } if (vec.back() == start) { ++start; --end; } } int layer = 0, am = 0, md = 0; bool flag=false; // 判断是否有内置括号 // 标记最后出现的加减乘除号位置(不在括号内) for (int i = start; i < end; ++i) { if (exp[i] == '(' || exp[i] == '[' || exp[i] == '{') { ++layer; flag=true; } else if (exp[i] == ')' || exp[i] == ']' || exp[i] == '}') { --layer; flag=true; } else if ((exp[i] == '+' || exp[i] == '-') && !layer) am = i; else if ((exp[i] == '*' || exp[i] == '/') && !layer) md = i; } // 若有加减号,则将符号前面的内容和后面的内容相加或减 if (am > start) { if (exp[am] == '+') return Calculation(exp, start, am) + Calculation(exp, am+1, end); else return Calculation(exp, start, am) - Calculation(exp, am+1, end); } // 若有乘除号,则将符号前面的内容和后面的内容相乘或者除 else if (md > start) { if (exp[md] == '*') return Calculation(exp, start, md) * Calculation(exp, md+1, end); else return Calculation(exp, start, md) / Calculation(exp, md+1, end); } // 若没有加减乘除,还要判断下是否有内置括号,比如((5+3)),若有则往里缩进 else if(flag) { return Calculation(exp, start+1, end-1); } // 若没有加减乘除,也没有内置括号,说明这部分内容是数字 else return stoi(exp.substr(start, end-start)); } int main() { string str; while (cin >> str) { cout << Calculation(str, 0, str.size()) << endl; } }