[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.pswp.cn/news/456536.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/456536.shtml
英文地址,請注明出處:http://en.pswp.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;整個…