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