您好,登錄后才能下訂單哦!
前面我們已經關于計算器介紹的已經夠多了,那么它現在還是沒有具備計算的功能。
今天我們來繼續講解計算器的解析算法,那么對于一個四則運算表達式,
它是如何讀懂的呢?比如:“+9.11 + ( -3 - 1 ) * -5 ”;
人類習慣的數學表達式叫做中綴表達式,還有一種將運算符放在數字后面的后綴表達式,
比如:5 + 3 ==> 5 3 +; 1 + 2 * 3 ==> 1 2 3 * +;像這種就是后綴表達式。
那么中綴表達式是符合人類的閱讀和思維習慣,后綴表達式則符合計算機的運算方式,
這是一種消除了中綴表達式中的括號,同時保留中綴表達式中的運算優先級。
解決方案就是:
1、將中綴表達式進行數字和運算符的分離
2、將中綴表達式轉換為后綴表達式
3、通過后綴表達式計算最終結果
所要計算的中綴表達式中包含
1、數字和小數點【0 - 9 或 . 】
2、符號位【 + 或 - 】
3、運算符【+,-,/, * 】
4、括號【 (或)】
具體的思想就是以符號作為標志對表達式中的字符逐個訪問
1、定義累計變量 num
2、當前字符 exp[i] 為數字或小數點時:
累計:num += exp[i];
3、當前字符 exp[i] 為符號時:
num 為運算數,分離并保存;
若 exp[i] 為正負號:
累計符號位 + 和 - : num += exp[i];
若 exp[i] 為運算符:
分離并保存;
用偽代碼描述出來就是這樣:
我們接下來分析下這個分離算法的難點在哪?當然是如何區分正負號與加號和減號。我們可以這樣想:正+ 和 負- 在表達式的第一個位置;括號后的 正+ 和 負- ;運算符后的 正+ 和 負-;
具體代碼則為:
QQueue<QString> QCalculatorDec::split(const QString& exp)
{
QQueue<QString> ret;
QString num = "";
QString pre = "";
for(int i=0; i<exp.length(); i++)
{
if( isDigitOrDot(exp[i]) ) // 判斷是否為數字0-9或小數點.
{
num += exp[i];
pre = exp[i];
}
else if( isSymbol(exp[i]) ) // 如果是符號
{
if( !num.isEmpty() ) // 數組不為空
{
ret.enqueue(num);
num.clear();
}
if( isSign(exp[i]) && ((pre == "") || (pre == "(") || isOperator(pre)) ) // 如果是正負號或者()或操作符
{
num += exp[i];
}
else
{
ret.enqueue(exp[i]);
}
pre = exp[i];
}
}
if( !num.isEmpty() )
{
ret.enqueue(num);
}
return ret;
}
我們在構造函數里設置如下:
那么我們構建運行完得到的結果如下:
那么我們可以看到計算器正確的識別了四則表達式,今天我們就先學習到這了。后面我們接著繼續計算器的解析算法的學習。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。