你知道計算機是怎麼計算加減乘除算式的麼?

說到加減乘除運算,只要學過乘法口訣的應該沒有不會算的吧。

什麼一一得一,一二得二.。。。信手拈來,簡直不要太容易。

難一點的無非也就是這四種運算符號組合起來而已,但是如此簡單的運算對於計算機而言,真的不是一件輕鬆的活啊。

就運算速度上,計算機遠超你我。

就運算簡易程度而言,你我勝過計算機。

為什麼這麼說呢?

下面舉個栗子,求一個算式(也叫中綴表達式)結果:5+(6-3)*4+8/2=?

對於我們而言,這個算式輕鬆的得到答案是21。那麼計算機,又是如何得出這個結果的呢?

談到這個問題,首先我們應該瞭解兩個知識:棧(stack)和後綴表達式

你知道計算機是怎麼計算加減乘除算式的麼?

  • 什麼是棧?

    棧又名堆棧,它是一種運算受限的線性表。其限制是僅允許在表的一端進行插入和刪除運算。這一端被稱為棧頂,相對地,把另一端稱為棧底。向一個棧插入新元素又稱作進棧、入棧或壓棧,它是把新元素放到棧頂元素的上面,使之成為新的棧頂元素;從一個棧刪除元素又稱作出棧或退棧,它是把棧頂元素刪除掉,使其相鄰的元素成為新的棧頂元素。

    可以這麼理解棧:棧相當於一個沒有瓶蓋的空瓶子。向瓶子內放入東西叫做入棧,從瓶子裡倒出東西叫做出棧。瓶底叫棧底,瓶口叫棧頂。雖然不是很恰當,但是這麼理解還是可以的。

  • 什麼是後綴表達式?

    後綴表達式也叫逆波蘭式。它是波蘭的邏輯學家盧卡西維奇(Lukasiewicz)發明的一種表示表達式的方法。這種表示方式把運算符寫在運算對象的後面,例如,把a+b寫成ab+,所以也稱為後綴式。這種表示法的優點是根據運算對象和算符的出現次序進行計算,不需要使用括號,也便於用械實現求值。對於表達式x:=(a+b)*(c+d),其後綴式為xab+cd+*:=。

計算機對上述運算表達式的過程大致分為兩個步驟:

①將中綴表達式轉換為後綴表達式

②通過執行後綴表達式得出結果

你知道計算機是怎麼計算加減乘除算式的麼?

首先介紹轉換為後綴表達式的過程。轉換的過程中遵循一個規則(符號進棧,數字輸出):

  • 從左到右遍歷中綴表達式的每個數字和符號

  • 如果是數字就加入後綴表達式

  • 如果是符號,判斷括號:如果是左括號“(”,直接入棧;是右括號“)”,則依次從棧中取出運算符加入後綴表達式中,直至取到“(”後停止,並且將棧中“(”刪除

  • 如果是括號以外的其他運算符,判斷這個運算符和棧頂符號優先級:其優先級低於或者等於棧頂符號則先將棧中符號依次彈出加入後綴表達式後自身入棧,否則自身就直接入棧


  • 直到遍歷中綴表達式結束,得到後綴表達式

詳細過程:

  • 將5輸出,+進棧; 目前輸出為5,棧中為+;

  • 遇到(,進棧; 目前輸出為5,棧底到棧頂依次為+ (;

  • 將6輸出,減號進棧,3輸出; 目前輸出為5 6 3,棧底到棧頂依次為+ (-;

  • 遇到),去匹配(,棧頂符號出棧,直到(出棧; 目前輸出為5 6 3-,棧中為+;

  • 遇到乘號進棧,6輸出;目前輸出為5 6 3 - 4,棧底到棧頂依次為+ *;

  • 遇到+,由於+的優先級比*低,所以棧中所有元素都出棧,自身進棧; 目前輸出為5 6 3 - 4 * +,棧底到棧頂依次為+;

  • 遇到10輸出,除號進棧;目前輸出為5 6 3 - 4 * + 8,棧底到棧頂依次為+/;

  • 遇到2輸出;目前輸出為5 6 3 - 4 *+ 8 2,棧底到棧頂依次為+/;

  • 表達式結束,棧中全部依次出棧,最終為5 6 3 - 4 * + 8 2 / +;

其次是後綴表達式的執行過程。其執行過程也遵循一個規則:

  • 從左向右遍歷後綴表達式的每個數字和符號,

  • 遇到是數字就進棧

  • 遇到是符號,就將處於棧頂兩個數字出棧,三者進行運算得到的運算結果進棧, 直到最後獲得運算結果

  • 5 6 3 依次進棧,然後遇到了減號;此時棧底到棧頂依次為5 6 3;

  • 處於棧頂的3和6出棧,相減得到3,將3進棧;此時棧底到棧頂依次為5 3;

  • 4進棧,然後遇到乘號;此時棧底到棧頂依次為5 3 4;

  • 處於棧頂的4和3出棧,相乘得到12,將12進棧;此時棧底到棧頂依次為5 12;

  • 遇到加號,處於棧頂的12和5出棧,加一下得到17,將17進棧;此時棧裡只有一個17;

  • 8 2依次進棧,然後遇到除號;此時棧底到棧頂依次為17 8 2;

  • 處於棧頂的2和8出棧,相除得到4,將4進棧;此時棧底到棧頂依次為17 4;

  • 遇到加號,處於棧頂的4和17出棧,想加得到21,將21進棧;

  • 表達式結束,輸出結果21,棧變空。

看完感覺怎樣?

是不是很複雜?

其實還好吧,233。。。

有的小夥伴可能又要吐槽了,知道這些過程有個屁用,實際工作中會讓你寫這個過程麼?

是的,工作可能不需要你瞭解底層如何計算,你需要告訴計算機這些數字和運算符,剩下的就等著拿到結果就ok。

我想說,編程重要的不是你能不能完成單純的開發任務,而是你能不能從任務中看到背後的編程思想。

思想決定高度!

思想有多遠,你就能走多遠~~~~~~~~

你知道計算機是怎麼計算加減乘除算式的麼?


分享到:


相關文章: