题目
给你一个字符串表达式 s ,请你实现一个基本计算器来计算并返回它的值。
例如1:输入 s=“1+1”
输出:2
例如2: 输入 s = "(1+(4+5+2)-3)+(6+8)"
输出:23
- s 由数字、'+'、'-'、'('、')'、和 ' ' 组成
- s 表示一个有效的表达式
思路
先去除空格
然后先找到右括号,再找到该有括号对应的左括号,在二者之间一定不再存在括号,计算该普通表达式的值
再将计算得到的结果,放回原先括号表达式的位置,重复上一步的运算过程
代码
#include <string>
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
class Solution {
public:
int calculate(string s) {
string str = remove_space(s);
return cal_simple(str);
}
string itoa(int num) {
char buffer[256];
sprintf(buffer, "%d", num);
return string(buffer);
}
private:
int cal_simple(string s) {
// 找出第一个)
size_t right_found = s.find(")");
while(right_found!=string::npos) { // 找到右括号
// 从该位置起反向找左括号
size_t left_found = s.rfind("(", right_found);
// 计算括号内表达式的值
string new_str = s.substr(left_found+1, right_found-left_found-1);
cout << "new expresion is " << new_str << endl;
int new_result = cal_simple(new_str);
cout << "new result is " << new_result << endl;
string next_str; // 新的表达式
// 将计算所得的结果放回原表达式中
if(left_found==0) { // 左括号在第一个元素
next_str = itoa(new_result) + s.substr(right_found+1); // TODO 会不会有越界问题
}else { // 左括号非第一个元素
string left_str = s.substr(0, left_found-1);
char left_oper = s.at(left_found-1);
if(left_oper=='+' && new_result < 0) {
left_oper = '-';
}else if(left_oper=='-' && new_result < 0) {
left_oper = '+';
}
left_str.push_back(left_oper);
if(new_result<0) {
new_result *= -1;
}
next_str = left_str + itoa(new_result);
if(right_found != s.length()-1) {
next_str += s.substr(right_found+1);
}
}
s = next_str; // 替代原先的表达式
cout << "now the expresion is " << next_str << endl;
// 寻找下一个右括号
right_found = s.find(")");
}
{ // 未找到
int left_num = 0; // 左操作数
int right_num = 0; // 右操作数
char oper = '+'; // 操作符
char next_operator = '+'; // 下一个操作符
int right_idx = 0; // 操作符所在的位置
if(s.at(0)=='+' || s.at(0)=='-') { // 首部为符号
oper = s.at(0);
right_idx = 1;
}
// 寻找下一个符号的位置
while(true) {
size_t next_plus_idx = s.find("+", right_idx);
size_t next_minus_idx = s.find("-", right_idx);
if(next_plus_idx==string::npos && next_minus_idx==string::npos) { // 没有符号了
break;
}
size_t next_idx = 0;
if(next_plus_idx!=string::npos && next_minus_idx!=string::npos) {
if(next_plus_idx<next_minus_idx) {
next_operator = '+';
next_idx = next_plus_idx;
}else {
next_operator = '-';
next_idx = next_minus_idx;
}
}else if(next_plus_idx!=string::npos) {
next_operator = '+';
next_idx = next_plus_idx;
}else {
next_operator = '-';
next_idx = next_minus_idx;
}
right_num = atoi(s.substr(right_idx, next_idx-right_idx).c_str());
if(oper=='+') {
left_num += right_num;
}else {
left_num -= right_num;
}
oper = next_operator;
right_idx = next_idx+1;
}
// 收尾工作
right_num = atoi(s.substr(right_idx).c_str());
if(oper=='+') {
return left_num + right_num;
}else {
return left_num - right_num;
}
}
return 0;
}
// 去掉空格
string remove_space(const string& str) {
string ret;
for(int i=0; i!=str.length(); i++) {
if(str.at(i)!=' ') {
ret.push_back(str.at(i));
}
}
return ret;
}
};