表示式求值-遞迴解法
阿新 • • 發佈:2021-01-05
技術標籤: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記錄運算子,每當遇到右括號,或者結尾,或者非數字=》需要將前面部分進行計算
對於+ - 那麼只需要一個運算數=》存入棧
對於* / 那麼還需要棧頂元素參與運算,結果入棧
對於( 那麼(之後的部分遞迴進行計算