[LeetCode]Basic Calculator

题目:Basic Calculator

给定一个合法的运算表达式,该表达式中只包含数字、'+'、'-'、' '、'('、')'。

思路:

简单思考不用看成加减两种运算,直接看成加法,只不过由正负;

如何处理括号呢?因为只看成加法,括号会影响的是数值的正负,那么通过去括号运算法则来修改当前值的正负就可以了。

具体来说,保存括号前的正负,括号内的正负都要乘以保存的正负。

int LeetCode::calculate(string s){int result = 0;vector<int>sign(2, 1);//当前元素的正负,如果输入是7-?可能会两次pop_back,为了不去判断是否为空for (size_t i = 0; i < s.size(); i++){if (s[i] >= '0'){//因为题目说只有数字、+、-、*、/、(、)、 这几种字符,其他都比数字小int k = 0;while (i < s.length() && isdigit(s[i]))k = k * 10 + s[i++] - '0';k = k*sign.back();result += k;sign.pop_back();--i;//i退回来
        }else if (s[i] == ')'){sign.pop_back();}else if (s[i] != ' '){//如果是左括号,就将括号展开,需要乘以括号外面的符号,所以要乘以sign.back()sign.push_back(sign.back()*(s[i] == '-' ? -1 : 1));}}return result;
}

题目:Basic CalculatorII

给定一个合法的运算表达式,该表达式中只包含数字、'+'、'-'、' '、'/'、'*'。

和上面相比增加了乘除,去掉了括号。

思路:

有了乘除就有不同的运算优先级,这里通过每次将加减的结果加到最终结果里面,使每次*/运算的时候,cur会从零开始,这样屏蔽了前面的运算结果过,从而避免的优先级的判断

int LeetCode::calculate(string s){int result = 0,cur = 0;char op = '+';//默认当前运算符为加for (size_t i = 0; i < s.size(); ++i){if (isdigit(s[i])){//数字int k = 0;while (i < s.length() && isdigit(s[i]))k = k * 10 + s[i++] - '0';//计算数值switch (op){case '+':cur = cur + k;break;case '-':cur = cur - k;break;case '*':cur = cur * k;break;case '/':cur = cur / k;break;default:return -1;//表达式有误
            }--i;}else if(s[i] != ' '){if (s[i] == '+' || s[i] == '-'){//加减运算符与顺序无关,由于没有括号,每次加减的值立即给resultresult += cur;cur = 0;}op = s[i];//遇到乘除的时候,cur总是从零开始的,所以前面的运算没有影响
        }}return result + cur;
}

思路:

其实,考虑第一题的思路,可以将加减法去掉,从而避免判断运算优先级,因为乘除的优先级是一样的;加减变成数字的符号,这样,每次就只用计算乘除;

int calculate(string s) {stack<int> myStack;char sign = '+';//保存运算符int res = 0, tmp = 0;for (unsigned int i = 0; i < s.size(); i++) {if (isdigit(s[i]))tmp = 10*tmp + s[i]-'0';//计算出数值if (!isdigit(s[i]) && !isspace(s[i]) || i == s.size()-1) {if (sign == '-')myStack.push(-tmp);//减法变成负数else if (sign == '+')myStack.push(tmp);//加法变成正数else {int num;//乘除运算if (sign == '*' )num = myStack.top()*tmp;elsenum = myStack.top()/tmp;myStack.pop();//将参与的上一个数值出栈myStack.push(num);//运算结果入栈
            } sign = s[i];tmp = 0;}}while (!myStack.empty()) {//所有的结果加起来res += myStack.top();myStack.pop();}return res;
}

以上的方法都是根据题意而取巧,如果放开运算表达式的限制,算法就不能用了。

思路:

这里有正常的通过双栈存储数值和运算符,遇到左括号运算符或数值都入栈,遇到运算符就先判断优先级,将要入栈的运算符优先级低于或等于栈顶的运算符就将栈顶的运算符出栈并计算数值,知道栈顶的运算符优先级较低;

优先级顺序从高到低如下:)> * >= / > + >= - > (;加减的优先级是一样的,但是栈顶的运算符优先级高于正在访问的运算符优先级,即:正在访问的'+'/'-' < 栈顶的'+'/'-'。

这样就可以按照通常的运算习惯让程序计算表达式的结果。

int LeetCode::calcu(stack<int>& num, stack<char>& sign){//运算符栈和数值栈出栈做运算if (num.empty())return -1;//表达式有误int k = num.top();num.pop();//都是双目运算符,还需要一个数if (num.empty())return -1;//表达式有误int m = num.top();num.pop();char ch = sign.top();sign.pop();int result = 0;switch (ch){case '+':result = m + k;break;case '-':result = m - k;break;case '*':result = m * k;break;case '/':result = m / k;break;default:return -1;//表达式有误
    }return result;
}int LeetCode::operatorPriority(char op1, char op2){//判断优先级if (op1 == '(' || op2 == '(')return false;if (op1 == '+' || op1 == '-'){if (op2 == '*' || op2 == '/')return false;}return true;
}int LeetCode::calculate(string s){stack<int>num;//数字栈stack<char>op;//符号栈int i = 0;while (i < s.length()){if (isdigit(s[i])){//是数字//拼接数字int k = 0;while (i < s.length() && isdigit(s[i]))k = k*10 + s[i++] - '0';num.push(k);continue;}else if (s[i] == ')'){//是右括号if (op.empty())return -1;if (op.top() == '('){op.pop();}else{//符号栈出栈并计算,知道遇到左括号,或某个栈为空while (!op.empty() && op.top() != '('){num.push(calcu(num, op));}op.pop();}++i;}else if (!isspace(s[i])){//非空格符,这里认为是运算符或左括号//下一个运算符入栈前先计算栈顶的运算符while (!op.empty() && operatorPriority(op.top(),s[i]))num.push(calcu(num, op));op.push(s[i]);}++i;}while (!op.empty()){num.push(calcu(num,op));}return num.top();
}

 

转载于:https://www.cnblogs.com/yeqluofwupheng/p/6810233.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/456536.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SPOJ 694/705 后缀数组

思路&#xff1a; 论文题*n Σn-i-ht[i]1 就是结果 O(n)搞定~ //By SiriusRen #include <cstdio> #include <cstring> #include <algorithm> using namespace std; #define N 55555 int cases,n,cntA[N],cntB[N],A[N],B[N],rk[N],sa[N],tsa[N],ht[N]; char…

如何用余弦定理来进行文本相似度的度量

在做文本分析的时候&#xff0c;经常会到说将文本转化为对应的向量&#xff0c;之后利用余弦定理来计算文本之间的相似度。但是最近在面试时&#xff0c;重复上面这句话&#xff0c;却被面试官问到&#xff1a;“什么是余弦定理&#xff1f;”当时就比较懵逼&#xff0c;于是把…

Mongodb 备份和恢复

为什么80%的码农都做不了架构师&#xff1f;>>> Mongodb 备份和恢复 mongodump -h host -u "username" -p "userpass" -d dbname -o backfilename tar -cvzf backfilename.tar backfilename tar -xvzf backfilename.tar mongorestore -h…

【linux】Ubuntu 18.04 设置桌面快捷启动方式

使用Ubuntu终端进行打开&#xff1a; 方法一&#xff08;使用vim&#xff09;&#xff1a; sudo vi /usr/share/applications/pycharm.desktop 方法二&#xff08;使用gedit&#xff09;&#xff1a; sudo gedit /usr/share/applications/pycharm.desktop 然后就会弹出一个…

在 Pycharm下使Python2和Python3共用Anaconda中的各种库/包的解决方法

参考&#xff1a;https://www.cnblogs.com/MoonST/p/7610460.html 目录&#xff1a;前言&#xff1a;1、同时下载两个版本的anaconda2、主版本conda的安装3、辅助版本Anaconda的安装 目录&#xff1a; 前言&#xff1a; 最近在看一些机器学习方面的教程&#xff0c;里面的一…

form表单元素设置只读

form表单元素设置只读 CreateTime--2017年5月5日11:42:41 Author:Marydon 1.设置文本框只读 <!-- 方法一&#xff1a;简写 --> <input type"text" name"" value"文本框" class"" readonly/> <!-- 方法二&#xff1a;…

MySQL安装和完全卸载-Linux ubantu18.04

MySQL数据库 千万不要安装5.7版本全是坑~&#xff01;&#xff01; 千万不要安装5.7版本全是坑~&#xff01;&#xff01; 千万不要安装5.7版本全是坑~&#xff01;&#xff01; ubantu18.04版本 正确道路应该是走安装MySQL 8.0&#xff1a; 第一步&#xff1a;更新文件…

机器学习中的数学基础相关知识总结

文章目录目录&#xff1a;前言&#xff1a;1、导数(曲线变化的快慢)、二阶导数&#xff08;曲线斜率变化的快慢特别是反映曲线的凸凹性&#xff09;的概念。2、常用的导数公式&#xff1a;3、微分和积分的数学含义&#xff1a;4、泰勒公式及含义5、梯度的概念及数学含义&#x…

Linux中python的开发环境配置(虚拟环境)

1 pyenv pyenv是一个Python版本管理工具&#xff0c;它能够进行全局的Python版本切换&#xff0c;也可以为单个项目提供对应的Python版本。使用pyenv以后&#xff0c;可以在服务器上安装多个不同的Python版本&#xff0c;也可以安装不同的Python实现。不同Python版本之间的切换…

第一个冲刺周期-第三天

一、先把数据库弄好&#xff0c;然后连接上&#xff0c;写一个测试用例&#xff0c;看看能不能调用数据&#xff0c; 增删改查是否正确&#xff0c;可以了的话&#xff0c;这一部分就结束了 二、 然后去写UI层&#xff0c;先写XML&#xff0c;把界面效果做出来 三、 然后写UI…

特征工程

上周参加了学校的数据挖掘竞赛&#xff0c;总的来说&#xff0c;在还需要人工干预的机器学习相关的任务中&#xff0c;主要解决两个问题&#xff1a;&#xff08;1&#xff09;如何将原始的数据处理成合格的数据输入&#xff08;2&#xff09;如何获得输入数据中的规律。第一个…

Linux下快速安装MySQL教程

转自&#xff1a;https://blog.csdn.net/sl1992/article/details/53634674 目录&#xff1a;前言&#xff1a;1.执行yum install mysql-server进行安装2.输入y进行确认3.安装成功4.查看MySQL是否启动5.启动MySQL6.查看是否运行7.设置开机启动MySQL8.创建MySQL管理员root9.登录M…

SpringMVC实战(注解)

1.前言 前面几篇介绍了SpringMVC中的控制器以及视图之间的映射方式,这篇来解说一下SpringMVC中的注解,通过注解能够非常方便的訪问到控制器中的某个方法. 2.配置文件配置 2.1 注解驱动,配置扫描器 首先须要在SpringMVC中的核心文件里指定注解驱动,详细例如以下: <?xml vers…

UIView类绘图出现错误提示

一:问题: Jan 16 15:49:53 CUBOT Band Ⅲ[2082] <Error>: CGContextSetLineWidth: invalid context 0x0. If you want to see the backtrace, please set CG_CONTEXT_SHOW_BACKTRACE environmental variable. Jan 16 15:49:53 CUBOT Band Ⅲ[2082] <Error>: CGCo…

Hbase2.0版本安装教程

目录&#xff1a;前言&#xff1a;1. 上传2. 解压3. 重命名4. 修改环境变量5. 修改配置文件6. 把hadoop的hdfs-site.xml和core-site.xml 放到hbase/conf下7. 发送到其他机器8. 启动9. 查看总结&#xff1a; 目录&#xff1a; 前言&#xff1a; 最近由于工作需要又把HBase重装…

MySQL8.0版本和5.7通过Navicat远程连接

首先在数据库创建好连接的用户 进入mysql服务器终端&#xff1a; 命令窗口终端&#xff1a; mysql -u用户名 -p密码 sudo mysql -uroot -p 创建用户部分-- 使用mysql 数据库 USE mysql&#xff1b; -- 为mysql创建用户&#xff1a;root1 密码为&#xff1a;root1 …

HUE配置文件hue.ini 的zookeeper模块详解(图文详解)(分HA集群)

不多说&#xff0c;直接上干货&#xff01; 我的集群机器情况是 bigdatamaster&#xff08;192.168.80.10&#xff09;、bigdataslave1&#xff08;192.168.80.11&#xff09;和bigdataslave2&#xff08;192.168.80.12&#xff09; 然后&#xff0c;安装目录是在/home/hadoop/…

CF #366(div.2) C 模拟,思维

CF #366(div.2) C. Thor 题意&#xff1a;一个手机n个联系人&#xff0c;有q个操作。每次给出ty和ai&#xff0c;如ty1&#xff0c;表示收到ai的一条信息&#xff1b;如ty2&#xff0c;表示将ai发的信息都看掉&#xff1b;如ty3&#xff0c;表示将第1条到第ai条信息都看掉…

MySQL基本指令汇总

创建数据库&#xff1a; create database 数据库名字; 删除数据库: drop database 数据库名字; 查看数据库: show databases; 切换数据库: use databasename; select database(); Create table 表名&#xff08;列名 数据类型 [约束]&#xff0c;列名 数据类型 [约束]&a…

linux命令行在任意目录下启动任意的脚本的方法

目录&#xff1a;前言&#xff1a;1、直接在命令行中设置PATH2、在profile中设置PATH3、在当前用户的profile中设置PATH 目录&#xff1a; 前言&#xff1a; 这应该算是一个常识吧&#xff0c;但是对于许多像我们这样的新手来说&#xff0c;一旦你出点小差错&#xff0c;整个…