C++ 支持加减乘三种运算和括号的计算器
刷题——支持加减乘三种运算和括号的计算器
以"12+(2*(3-4))*5"为例子,利用递归的方法。
//以"12+(2*(3-4))*5"为例子 int solve(string s) { //返回对应数值 if (s.empty()) return 0; else { int result = 0; for (size_t i = 0; i < s.size(); i++)//如果是数字,例如“12”,返回对应数值12 if (s[i] >= '0'&&s[i] <= '9') { result = 10 * result + (s[i] - '0'); if (i == s.size() - 1) return result; } else//如果是式子,例如“2*(3-4)”,则继续运行,将式子分块 break; } //将式子分块 vector<string> elems;//保存元素块,如“12”,“2*(3-4)”,“5”等 vector<char> op; //保存该层式子的运算符(不包括在括号中的) op.push_back('+');//为了将结果加入result第一个运算符必须是+ vector<char> left;//记录左括号数量 vector<char> right;//记录右括号数量 int i = 0;//当前元素块 for (auto it = s.begin(); it != s.end(); ) { if (*it >= '0'&&*it <= '9')//将数值型元素块加入elems { elems.push_back(""); for (; it != s.end() && *it >= '0'&&*it <= '9'; ++it) elems[i].push_back(*it); ++i; } else if (*it == '+' || *it == '-' || *it == '*')//将运算符加入op { op.push_back(*it); ++it; } else if (*it == '(')//将式子(带括号)元素块去掉最外侧括号后加入elems { elems.push_back(""); std::string& temp = elems[i]; while (it != s.end() && (left.size() != right.size() || *it == '(')) { if (*it == '(') left.push_back(*it); else if (*it == ')') right.push_back(*it); temp.push_back(*it); ++it; } temp = temp.substr(1, temp.size() - 2);//去掉最外侧括号 ++i; } else ++it; } //计算当前分式子的值 int result = 0; for (int i = 0;i < op.size();++i) { char o = op[i];//当前运算符 if (i + 1 < op.size())//由于乘法运算*是优先的,所以需要先预测后一位运算符是不是* { int temp = solve(elems[i]); while(i+1<op.size()&&op[i + 1] == '*')//如果后面的*,则先乘起来 { temp *= solve(elems[i + 1]); ++i; } switch (o)//再更加当前符号进行加减处理 { case '+':result += temp;break; case '-':result -= temp;break; } } else//由于乘法必然已经运算,所以剩下的只有加减法运算。 { switch (o) { case '+':result += solve(elems[i]);break; case '-':result -= solve(elems[i]);break; } } } return result;//返回结果 }
该方法代码量较大,约90行。有的方法的代码量只有30行左右,但本人能力有限,独自想不出来。