您的位置:首页 > 其它

Leetcode 227. Basic Calculator II

2016-02-29 14:19 309 查看

Problem

mplement a basic calculator to evaluate a simple expression string.

The expression string contains only non-negative integers, 
+
-
*
/
 operators
and empty spaces 
. The integer division should truncate toward zero.

You may assume that the given expression is always valid.

Some examples:

"3+2*2" = 7
" 3/2 " = 1
" 3+5 / 2 " = 5


Note: Do not use the 
eval
 built-in
library function.

Credits:

Special thanks to @ts for adding this problem and creating all test cases。

我的想法就是用两个stack, 一个记数字,一个记操作符,

写出来的代码好丑。。

class Solution {
bool isOpt( const char& ch) {
if(ch == '+' || ch == '-' || ch == '*' || ch == '/') return true;
return false;
}
void calc( stack<int>& num_stk, stack<char>& opt_stk){
int num2 = num_stk.top(); num_stk.pop();
int num1 = num_stk.top(); num_stk.pop();
char opt = opt_stk.top(); opt_stk.pop();

int rst = 0;
switch( opt) {
case '+' :
rst = num1 + num2;
break;
case '-' :
rst = num1 - num2;
break;
case '*' :
rst = num1 * num2;
break;
case '/' :
rst = num1 / num2;
break;
}
num_stk.push(rst);
}

public:
int calculate(string s) {
const int N = s.size();
stack<int> num_stk;
stack<char> opt_stk;

unordered_map<char,int> preced;
preced['+'] = 0; preced['-'] = 0; preced['*'] = 1; preced['/'] = 1;

for( int i = 0; i < N; i++) {
if( s[i] == ' ') continue;

if(isdigit(s[i])){
int num = 0;
while( i < N && !isOpt(s[i])) {
if(s[i] == ' ') { i++;continue;}
num = num*10 + s[i] -'0';
i++;
}
i--;
num_stk.push(num);
}
else {
if(opt_stk.empty() || preced[s[i]] > preced[opt_stk.top()]){
opt_stk.push(s[i]);
}
else{
calc(num_stk, opt_stk);
i--;
}
}
}

while( !opt_stk.empty() ){
calc(num_stk, opt_stk);
}
return num_stk.top();
}
};


优化版

这个想法比较巧妙 : 第一步就只是去处乘号和除号,第二步就计算加减号

class Solution {

public:
int calculate(string s) {
char preSign = '+';
int pre_num = 0;
stack<int> num_stk;

const int N = s.size();
for( int i = 0; i < N; i++){
if(isdigit(s[i])) {
pre_num = pre_num*10 + s[i] - '0';
}
if( ( !isdigit(s[i]) && s[i] != ' ')|| i == N -1 ) {
int top = 0;
switch (preSign) {
case '+' :
num_stk.push(pre_num);
break;
case '-' :
num_stk.push(-pre_num);
break;
case '*' : {
top = num_stk.top(); num_stk.pop();
num_stk.push(top * pre_num);
break;}
case '/' :{
top = num_stk.top(); num_stk.pop();
num_stk.push(top/pre_num);
break;}
}
preSign = s[i];
pre_num = 0;
}
}

int rst = 0;
while(!num_stk.empty()){
int top = num_stk.top();
num_stk.pop();
rst += top;
}
return rst;
}
};


问题升级:
如果表达式中还有 ( 和 ) ,怎么办 
写出来有问题,回头再看吧。。。 写的有点烦躁。。。。
stack<int> num_stk;
stack<char> opt_stk;

void do_calc(){
int num1 = num_stk.top(); num_stk.pop();
int num2 = num_stk.top(); num_stk.pop();

char opt = opt_stk.top(); opt_stk.pop();
int rst = 0;
switch(opt){
case '+' :
rst = num2 + num1;
break;
case '-':
rst = num2 - num1;
break;
case '*' :
rst = num2 * num1;
break;
case '/':
rst = num2 / num1;
break;
}
num_stk.push(rst);
}

int calc( const string& str) {

unordered_map<char,int> preced;
preced['*'] = 1; preced['/'] = 1;preced['+'] = 0;preced['-'] = 0;preced['('] = -1;

const int N = str.size();

for( int i = 0; i < N; i++){
// for numbers
if(str[i] == ' ') continue;
if(isdigit(str[i])){
int num = 0;
for( ; i < N ; i++ ) {
if(str[i] == ' ') continue;
if(!isdigit(str[i])) break;
num = num*10 + str[i] - '0';
}
num_stk.push(num);
}

4000
// for operators
if(opt_stk.empty() || str[i] == '(' || preced[str[i]] > preced[opt_stk.top()]) {
opt_stk.push(str[i]);
}
else if( preced[str[i]] <= preced[opt_stk.top()]) {
do_calc();

}
else if(str[i] == ')') {
while(opt_stk.top() != '(') {
do_calc();
}
opt_stk.pop();
}
}

while(!opt_stk.empty()){
do_calc();
}
return num_stk.top();
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  stack