1. 程式人生 > 其它 >表示式求值-遞迴解法

表示式求值-遞迴解法

技術標籤:Leetcode

文章目錄


給定一個字串str,str表示一個公式,公式裡可以有整數,加減乘除和左右括號,返回公式的計算結果(注意:題目中所有運算都是整型運算,向下取整,且保證資料合法,不會出現除0等情況)。

輸入
48*((70-65)-43)+8*1
輸出
-1816

傳統思路

一般而言,表示式求值,先將中綴表示式轉化為字尾表示式=》進一步進行求解

本題採取,遞迴思路

cal(string s,int k)表示從串s的第k個往後計算一個單位

這裡一個最小計算單位是,遇到右括號,或者遇到串結尾

程式碼實現

pair<int,int> calc(
string s,int k) { int res=0; int num=0; int i; char sign = '+'; stack<int> st; for (i=k; i<s.length() && s[i] != ')'; i++) { if (s[i] >= '0' && s[i] <= '9') { num = num*10 + int (s[i]-'0'); } if(!isdigit
(s[i]) || i==s.length()-1 || s[i+1]==')') //如果後面一個是)或者末尾 需要結算 { if(s[i]=='(') //左括號 那麼其後面部分遞迴求解 { auto r=calc(s,i+1); num=r.first; i=r.second; } if(sign=='-' || sign=='+') //加減 {
st.push((sign=='-' ? -num : num)); } else if(sign=='*' || sign=='/') //乘除需要用到前一個數字 { int t=st.top();//取上一個數字 st.pop(); st.push((sign=='*' ? t*num : t/num)); } num=0; sign=s[i];//調整到下一個符號 } } while(!st.empty()) //剩餘棧中的數 相加 { res+=st.top(); st.pop(); } return make_pair(res,i); } int main() { string str; cin>>str; cout<<calc(str,0).first<<endl; }

關鍵點

採取sign記錄運算子,每當遇到右括號,或者結尾,或者非數字=》需要將前面部分進行計算

對於+ - 那麼只需要一個運算數=》存入棧
對於* / 那麼還需要棧頂元素參與運算,結果入棧
對於( 那麼(之後的部分遞迴進行計算