LeetCode OJ——Basic Calculator
2015-12-01 10:47
309 查看
题目:
Implement a basic calculator to evaluate a simple expression string.
The expression string may contain open ( and closing parentheses ), the plus + or minus sign -, non-negative integers and empty spaces .
You may assume that the given expression is always valid.
Some examples:
“1 + 1” = 2
” 2-1 + 2 ” = 3
“(1+(4+5+2)-3)+(6+8)” = 23
Note: Do not use the eval built-in library function.
代码:
结果:
思路:
第一步是将字符串中的空格字符去掉
第二步则是将字符串分裂,例s=”1 - 1 2 + ( 3 - 34)”,则分裂后的子串放置在容器中vec_s : “1”, “-“, “12”, “+”, “(“, “3”, “-“, “34”, “)”
第三部是对入栈出栈操作进行运算:
(a) 当遍历的容器中的字符串为“(”号时,入栈
(b) 当该字符串为数字时,入栈
(c) 当该字符串为”+”时,则考虑是否可以进行运 算。因为字符串中只存在+或 -, 因此运算符优先级 相同,只要碰到可以运算的字符串,则可先进行计 算。tmp中存储的是stk.top()的值,即当前字符串 的前一字符串。当”+”号前后均是数字时则可进行 运算。所以要考虑后一字符串是否也为数字, isdigit(vec_s[i + 1][vec_s[i + 1].size() - 1])只对后 一字符串的最后一位字符是否为数字进行判别,其 理由是vec_s[i+1]只有可能是 “(” 或 “)”或“[- ]1XXX”,若最后一位为数字其结果必然也是数 字。同理,isdigit(tmp[tmp.size()-1])。
(d)当为”-“时,同”+”原理。
(e)当为”)”时,则栈中一定存在”(“,切”( )”构成一&个封闭的运算,则该()种的式子一定已经运算过,即栈中存储结构为 ….,(, 数字 。则此时应该出栈2次,将(和数字均出栈。由于合法的字符 中“(”的前面要么是+/-;要么前面没有任何有效字符符,即(已经在最前面。若前面是+/-,则可以更进一步,按照(c)或(d)计算。
(f)将容器遍历完,栈中也只剩最后运算后的结果,返回结果即可
总结:
算法时间复杂度还比较大,算法还需改进。小菜鸟,加油!!!↖(^ω^)↗
Implement a basic calculator to evaluate a simple expression string.
The expression string may contain open ( and closing parentheses ), the plus + or minus sign -, non-negative integers and empty spaces .
You may assume that the given expression is always valid.
Some examples:
“1 + 1” = 2
” 2-1 + 2 ” = 3
“(1+(4+5+2)-3)+(6+8)” = 23
Note: Do not use the eval built-in library function.
代码:
class Solution { public: int calculate(string s) { stack<string> stk; string tmp, ss; ostringstream oss; //s.erase(0, s.find_first_not_of(" ")); // 去掉头部空格 //s.erase(s.find_last_not_of(" ") + 1); // 去掉尾部空格 vector<string> vec_s; for (unsigned i = 0; i < s.length(); i++) //去掉空格 { if (s[i] != ' ') { ss.push_back(s[i]); } } s = ss; unsigned i = 0; ss.clear(); while (i < s.length()) //将s分裂成新的字符串,例 "1 - 1 2 + ( 3 - 34)" { //转换成"1", "-", "12", "+", "(", "3", "-", "34", ")" //ss.clear(); if (isdigit(s[i])) { ss.push_back(s[i]); i++; } else{ if (!ss.empty()) { vec_s.push_back(ss); ss.clear(); } ss.push_back(s[i]); vec_s.push_back(ss); ss.clear(); i++; } } if (!ss.empty()) { vec_s.push_back(ss); ss.clear(); } ss.clear(); if (vec_s.size() == 0) //容器为空,表明s不存在非空格字符 { return 0; } else if (vec_s.size() == 1) //容器长度为1,表明s只含有数字字符 { return atoi(vec_s[0].c_str()); } else{ tmp.push_back(s[0]); stk.push(vec_s[0]); for (unsigned i = 1; i < vec_s.size(); i++) { if (vec_s[i] == "(") //当前字符为'(' { tmp.clear(); tmp.push_back('('); stk.push(tmp); //stk.push(vec_s[i]); } else if (vec_s[i] == "+") //当前字符为+ { //栈顶元素为数字,+号后面的字符s[i+1](+号后面一定存在字符,否则字符串不合法)也为数字,即+号前后都为数字可运算 if (isdigit(tmp[tmp.size()-1]) && isdigit(vec_s[i+1][vec_s[i+1].size()-1])) { //tmp.pop_back(); //此时tmp中原先存储的数字并没有消去 oss.str(""); oss << atoi(tmp.c_str()) + atoi(vec_s[i+1].c_str()); tmp = oss.str(); stk.pop(); stk.push(tmp); //将运算后的数字入栈 i++; } else{ tmp.clear(); //每次入栈前都将tmp清空 tmp = vec_s[i]; stk.push(tmp); } } else if (vec_s[i] == "-") //当前字符为- { //栈顶元素为数字,-号后面的字符s[i+1](-号后面一定存在字符,否则字符串不合法)也为数字,即-号前后都为数字可运算 if (isdigit(tmp[tmp.size()-1]) && isdigit(vec_s[i + 1][vec_s[i + 1].size() - 1])) { oss.str(""); oss << (atoi(tmp.c_str()) - atoi(vec_s[i + 1].c_str())); //-号前后元素都为数字,故可进行运算 tmp = oss.str(); stk.pop(); stk.push(tmp); //将运算后的数字入栈 i++; } else{ tmp.clear(); tmp = vec_s[i]; stk.push(tmp); } } else if (isdigit(vec_s[i][vec_s[i].size() - 1])) //当前字符为数字 { tmp.clear(); tmp = vec_s[i]; stk.push(tmp); } else if(vec_s[i] == ")") //当前字符为')',表示栈中一定存在'(' { tmp = stk.top(); //栈顶元素为当前()中运算的值 stk.pop(); //删除运算值 stk.pop(); //此时,删除的是'(' if (!stk.empty())//若此时的栈不为空 { if (stk.top() == "+") //删除的(号前是+号 { stk.pop(); //先把加号出栈 oss.str(""); oss << (atoi(stk.top().c_str()) + atoi(tmp.c_str())); //加号前面的数字加上旧的tmp值 } if (stk.top() == "-") //删除的(好前面是-号 { stk.pop(); //先把减号出栈 oss.str(""); oss << (atoi(stk.top().c_str()) - atoi(tmp.c_str())); //减号前面的数字减上旧的tmp值 } tmp.clear(); tmp = oss.str(); stk.pop(); //把+或-号前参与运算的数也去掉 } stk.push(tmp); //将运算后的值入栈 } else //当前字符为空格 { ; } } return atoi(stk.top().c_str()); } } };
结果:
思路:
第一步是将字符串中的空格字符去掉
第二步则是将字符串分裂,例s=”1 - 1 2 + ( 3 - 34)”,则分裂后的子串放置在容器中vec_s : “1”, “-“, “12”, “+”, “(“, “3”, “-“, “34”, “)”
第三部是对入栈出栈操作进行运算:
(a) 当遍历的容器中的字符串为“(”号时,入栈
(b) 当该字符串为数字时,入栈
(c) 当该字符串为”+”时,则考虑是否可以进行运 算。因为字符串中只存在+或 -, 因此运算符优先级 相同,只要碰到可以运算的字符串,则可先进行计 算。tmp中存储的是stk.top()的值,即当前字符串 的前一字符串。当”+”号前后均是数字时则可进行 运算。所以要考虑后一字符串是否也为数字, isdigit(vec_s[i + 1][vec_s[i + 1].size() - 1])只对后 一字符串的最后一位字符是否为数字进行判别,其 理由是vec_s[i+1]只有可能是 “(” 或 “)”或“[- ]1XXX”,若最后一位为数字其结果必然也是数 字。同理,isdigit(tmp[tmp.size()-1])。
(d)当为”-“时,同”+”原理。
(e)当为”)”时,则栈中一定存在”(“,切”( )”构成一&个封闭的运算,则该()种的式子一定已经运算过,即栈中存储结构为 ….,(, 数字 。则此时应该出栈2次,将(和数字均出栈。由于合法的字符 中“(”的前面要么是+/-;要么前面没有任何有效字符符,即(已经在最前面。若前面是+/-,则可以更进一步,按照(c)或(d)计算。
(f)将容器遍历完,栈中也只剩最后运算后的结果,返回结果即可
总结:
算法时间复杂度还比较大,算法还需改进。小菜鸟,加油!!!↖(^ω^)↗
相关文章推荐
- oracle exp imp 备份 还原
- .NET(C#):await返回Task的async方法
- PHP开启伪静态配置
- Linux 分区注意事项
- 分享PHP源码批量抓取远程网页图片并保存到本地的实现方法
- android下的事件分发
- QoS/ToS/CoS/DSCP 介绍
- python转C的内存泄露问题
- sample questions
- AngularJS的Provider, Value, Constant, Service, Factory, Decorator的区别与详解
- 常见算法:C语言求素数的问题
- jsp九大内置对象详解
- NET 二维码生成
- Python缩小图像
- 获取图片某一点的rgb色值
- Xcode7中安装及使用Alcatraz来管理Xcode插件
- 【Leetcode】Single Number II
- C - 指针 Homework
- 南大软院大神养成计划--day16
- ZIP 压缩解压命令