很久之前寫過,用棧實現四則運算,現在會看當時的實現有兩個問題:
1.使用自己實現的容器,不夠通用
2.**實現的封裝性不夠
此次在原先的基礎上,使用c++重構,直接使用stl容器類來實現四則運算。
這裡不再贅述,方法和注意事項參考之前文章理論部分
最通用的方法就是使用兩個棧,分別對運算數和運算子壓棧出棧實現運算子優先順序計算,核心函式為算符比較函式。如下,注意這裡的優先順序構造技巧,和老文章的方法不太一樣,更直觀簡單。
//核心函式,確定兩個運算子的優先順序,以此決定入棧出棧還是計算
e_level_compare compareoperator(const char c1, const char c2) const
//括號和#匹配匹配,表示需要將兩個符號範圍內運算完成
if ((c1 == '(' && c2 == ')') ||
(c1 == '#' && c2 == '#'))
//(和)優先計算
if (c1=='(' || c2=='(')
if (c1 == ')' || c2 == ')')
//剩下的按照預先設定的運算子表對映來查詢和比較優先順序,注意這裡相同的優先順序,前者大於後者
return m_op_level.at(c1) < m_op_level.at(c2) ? e_level_smaller : e_level_larger;
}cstackcalc()
,,,,,,, };
}
不斷讀入和判斷優先順序即可,遇見高優先順序的算符壓棧,遇見低優先順序的算符出棧計算,如下:
bool calcexpression(const string str)
else
m_num.push(num);
break;
}} }
if (m_op.size()!=0 || m_num.size()!=1)
cout << "計算結果為:" << m_num.top() << endl;
return true;
}
演算法2就是之前說的後序表示式法(逆波蘭式)。
其實現在再看,後序表示式法其實和演算法1很像,只不過是把演算法1拆分成了生成後序表示式和計算後序表示式兩步。
先看生成後序表示式,其實和演算法1基本一樣,無非是把出棧計算換成了生成後序表示式佇列。
bool converttopostexp(const string str)
});movetonext(&p);
} else
});m_op.pop();
break;
}} }
if (m_op.size()!=0)
cout << "後序表示式為:" << endl;
for (auto iter = m_exp.begin(); iter!=m_exp.end(); iter++)
else
}return true;
}
再看計算後序表示式,其實就是順序出佇列計算
bool calcexpression(const string str)
//依次彈出數字和運算子完成計算
for (auto iter=m_exp.begin(); iter!=m_exp.end(); iter++)
else
m_num.push(num);
} }if (m_num.size() != 1)
cout << "計算結果為:" << m_num.top() << endl;
return true;
}
算術表示式求值(四則運算)
1.只考慮 這幾個基本運算子,且是二元操作 2.運算數隻考慮 0 9,這10個簡單的數,方便從string中取出來 3.輸入的表示式沒有語法錯誤 背景知識 中綴表示法 infix expression 操作符位於兩個運算元中間,算術表示式的常規表示法。只用於二元操作符的情況,而且需要用括號和優先規則...
棧的應用 四則運算(字尾表示式)
那麼字尾表示法如何寫出來的呢?先看乙個簡單的例子 乙個中綴四則表示式 9 3 1 x3 10 2 變成字尾表示式 9 3 1 3 x 10 2 那麼它是怎麼變的呢?先別急,我們先來看看計算機是如何計算字尾表示式的。規則 從左到右遍歷表示式的每個數字和符號,遇到數字就進棧,遇到符號就將棧頂的兩個數字出...
四則運算表示式求值(棧的應用)
1.前 中 字尾表示式的轉換 首先需要明白三者之間的轉換 自然表示式轉換為前 中 字尾表示式,其實是很簡單的。首先將自然表示式按照優先順序順序,構造出與表示式相對應的二叉樹,然後對二叉樹進行前 中 字尾遍歷,即得到前 中 字尾表示式。舉例說明將自然表示式轉換成二叉樹 a b c d 根據表示式的優先...