双栈完全解决计算器问题
生活随笔
收集整理的這篇文章主要介紹了
双栈完全解决计算器问题
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
文章目錄
- 題目
- 題目分析
- 代碼拆解
- 預(yù)處理
- 關(guān)鍵求值函數(shù)calc()
- 括號處理
- 數(shù)字和字符處理
- 綜合代碼得出答案
題目
我就口頭描述一遍吧:把給出的表達(dá)式字符串計算它的算式結(jié)果并返回。其中表達(dá)式只含有:’+’、’-’、’*’、’/’、空格、數(shù)字。。。這些字符。
而對于表達(dá)式可能會出現(xiàn):3+(2*-2) or 7+(-34+5)..等特殊情況。
題目分析
對于這種算式計算我們一般采用雙棧形式:
- 數(shù)字處理棧:用于存儲表達(dá)式中的數(shù)字。
- 字符處理棧:用于存儲各種運算符以及括號。
而我們?nèi)绾翁幚磉@樣一個計算過程呢?
對于數(shù)字,一旦掃描到一個數(shù)字的開頭,就一直連續(xù)掃描到結(jié)尾進(jìn)行數(shù)字更新,最后的結(jié)果再乘以符號標(biāo)記。
對于字符,一旦掃描到字符后,字符串的前一個仍然是字符,則該字符只可能是代表數(shù)字的符號,所以此字符不入棧,僅僅作為更新數(shù)字符號的標(biāo)記,其他情況就根據(jù)優(yōu)先級判斷上一個運算符的優(yōu)先級是否大于等于當(dāng)前的運算符,如果是,則開始計算答案。
如果到最后字符棧還有運算符則繼續(xù)計算,直到為空
代碼拆解
預(yù)處理
去空格
void preCond(string& s){int i = s.find(' ');while(i!=-1){s.replace(i,1,"");i = s.find(' ');}}置0,設(shè)置優(yōu)先級和符號標(biāo)記(默認(rèn)為正)
nums.push_back(0);prior['+'] = prior['-'] = 1;prior['*'] = prior['/'] = 2;int syb = 1;關(guān)鍵求值函數(shù)calc()
int calc(){int b = nums.back();nums.pop_back();int a = nums.back();nums.pop_back();char op = ops.back();ops.pop_back();switch(op){case '+':return a+b;case '-':return a-b;case '*':return a*b;case '/':return a/b;}return -1;}括號處理
//括號處理if(op=='(') ops.push_back(op);else if(op==')'){while(!ops.empty()){if(ops.back()!='(')nums.push_back(calc());else {ops.pop_back();break;}}}數(shù)字和字符處理
//數(shù)字和符號處理(碰到強(qiáng)行2*-3的情況,直接在入數(shù)字的時候入-3,符號'-'不要計入符號棧)else{if(isdigit(op)){int j = i;int num = 0;while(isdigit(s[j])){num = num*10 + (s[j++]-'0');}nums.push_back(num*syb);syb = 1;i = j-1;}else{if(i>0&& s[i-1]=='(' or s[i-1]=='*' or s[i-1]=='/' or s[i-1]=='+' or s[i-1]=='-'){if(op=='-')syb = -1;}else{while(!ops.empty()&&prior[ops.back()]>=prior[op]){nums.push_back(calc());}ops.push_back(op);}}}}while(!ops.empty()){nums.push_back(calc());}綜合代碼得出答案
還好效率還行!
class Solution { public:int calculate(string s) {//預(yù)處理三件事:1.消除空格 2.防止最開始有符號設(shè)置了最開始0入棧 3.用數(shù)組設(shè)置優(yōu)先級preCond(s);nums.push_back(0);prior['+'] = prior['-'] = 1;prior['*'] = prior['/'] = 2;int syb = 1;for(int i=0;i<s.size();i++){char op = s[i];//括號處理if(op=='(') ops.push_back(op);else if(op==')'){while(!ops.empty()){if(ops.back()!='(')nums.push_back(calc());else {ops.pop_back();break;}}}//數(shù)字和符號處理(碰到強(qiáng)行2*-3的情況,直接在入數(shù)字的時候入-3,符號'-'不要計入符號棧)else{if(isdigit(op)){int j = i;int num = 0;while(isdigit(s[j])){num = num*10 + (s[j++]-'0');}nums.push_back(num*syb);syb = 1;i = j-1;}else{if(i>0&& s[i-1]=='(' or s[i-1]=='*' or s[i-1]=='/' or s[i-1]=='+' or s[i-1]=='-'){if(op=='-')syb = -1;}else{while(!ops.empty()&&prior[ops.back()]>=prior[op]){nums.push_back(calc());}ops.push_back(op);}}}}while(!ops.empty()){nums.push_back(calc());}return nums.back();} private:int prior[128] = {0};vector<int>nums;vector<char>ops;int calc(){int b = nums.back();nums.pop_back();int a = nums.back();nums.pop_back();char op = ops.back();ops.pop_back();switch(op){case '+':return a+b;case '-':return a-b;case '*':return a*b;case '/':return a/b;}return -1;}void preCond(string& s){int i = s.find(' ');while(i!=-1){s.replace(i,1,"");i = s.find(' ');}} }; ```總結(jié)
以上是生活随笔為你收集整理的双栈完全解决计算器问题的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 视觉SLAM十四讲:运动方程
- 下一篇: gym101532 2017 JUST