棧的應用1 超級計算器(中綴與字尾表示式)C語言

2022-04-21 22:10:28 字數 4273 閱讀 6205

這裡要學的程式主要用來實現乙個功能——輸入表示式輸出結果,也就是乙個計算器。效果如下:

這個程式主要有兩個步驟:1、把中綴表示式轉換為字尾表示式;2、計算字尾表示式的結果。

首先先明白幾個問題:

2、怎麼把中綴表示式轉換為字尾表示式?

3、怎麼用字尾表示式輸出結果?

相信如果弄明白了上面幾個問題,有c語言基礎的同學就可以編出這個程式啦。而後面兩個問題都要用到乙個資料結構——棧。實際上資料結構只是一種思想,一種思維,是連線人腦與計算機的橋梁(純屬個人杜撰= =)

好,那麼我們先學怎麼把中綴表示式轉換為字尾表示式。

1、設定乙個棧,棧底填乙個"@"作為結束符(當然也可以用別的符號,至於為什麼要用一會講優先順序的時候會說);

2、開始逐個字元讀入;

3、如果讀入的是數字,直接列印printf("%c ",c);(數字後面列印乙個空格作為間隔符,要不然沒法看了931-。。。不解釋)

4、如果讀入的是"("直接進棧;

5、如果讀入的是")",說明前面肯定讀入過乙個"("找到這個左括號,把兩者之間的符號逐個彈棧(這裡要說明的是,括號不必列印,因為字尾表示式沒有括號);

6、如果不是上面的幾種情況,那必定是+-*/中的乙個啦,這樣來說就容易多了。本來這裡應該說優先順序的問題,可是我還是想先說說棧。講到這裡,實際上大家應該也看出來了,棧實際上就是乙個進棧和出棧的問題,這裡也是一樣,對於表示式這裡我們可以發現,這個棧是用來儲存符號的,()+-*/,所以我們只需要明白什麼時候符號可以進棧,什麼時候符號可以出棧就可以啦~上面已經講了兩個了,左括號的時候直接可以進棧,右括號的時候把兩者之間的出棧列印。而對於+-*/,只需要記住乙個法則,對於讀入的這個符號,只有它比棧頂符號的優先順序高的時候才可以進棧(優先順序相同也不能進棧),而它不能進棧,就只能讓棧頂的出棧啦~所以不斷出棧,知道這個符號可以進棧,這個新讀入的符號就算處理完成啦。(優先順序函式可以參照後面的程式**)

ok,按照上面的演算法,掃瞄完一遍讀入的中綴表示式,就可以在螢幕上輸出字尾表示式啦。下面附上自製**(c語言,帶注釋):

1 #include2 #include3

#define newp (stype *)malloc(sizeof(stype)) //

定義乙個申請棧位址的巨集

4 typedef struct

_stack stype; //

建立棧型別

8int tance(char x) //

探測優先順序 914

intmain()

1529

else

if (c=='

(') //

如果是左括號,直接進棧

3036

else

if (c=='

)') //

如果是右括號,匹配左括號,把兩者之間的棧內符號全部彈出

3745 s=top;

46 top=top->next;

47free

(s);48}

49else

//否則肯定是+-*/了

5060

else

//否則就把棧頂的符號一直彈出,直到彈到可以壓進去,然後壓進去(也就是說等於也不能壓進去)

6170 s=newp;

71 s->dat=c;

72 s->next=top;

73 top=s;74}

75}76 c=getchar(); //

讀取下乙個字元 77}

78while (top->dat!='

@') //

讀完和還不算完,還要把棧內剩餘的所有符號挨個彈出

7985

return

0; //

字尾表示式輸出完畢

86 }

好,如果你看懂了上面所有的內容,恭喜你,已經學會一半了。那麼,現在我們就可以去掉那個只能輸入一位數的大前提,只需要在輸入的時候處理一下,就可以實現任意位數的數,甚至是小數(可以參照最後的程式**)。

那麼現在我們來完成第二步:已知字尾表示式輸出結果。這個演算法要比上面的轉換簡單多了,就是棧的基本操作,只不過這裡的棧不是用來儲存字元的,而是用來儲存數字的。

我們不妨還是假設一位數吧。

1、如果讀入的是數字,直接進棧;

2、如果是符號,必然是+-*/中的乙個,直需要彈出棧頂的兩個數,運算,然後再把結果進棧。直至掃瞄完整個字尾表示式,棧頂就是最終結果。

如果看懂了上面,我們可以發現,這個過程直接就可以在轉換表示式的時候順便完成,也就是,如果遇到數字,不列印到螢幕上,而是進棧到數字儲存棧裡;如果有出棧的符號,不用列印到螢幕上,而是彈出數字棧的兩個棧頂元素,然後進棧。就ok啦。下面附上輸入中綴表示式輸出結果的**(只是將上面的**中列印的過程換成了其他操作而已):

1 #include2 #include3

4#define newp (stype *)malloc(sizeof(stype)) //

定義乙個申請棧位址的巨集

56 typedef struct

_stack stype; //

建立棧型別

1011

int tance(char x) //

探測優先順序

1217

18int

main()

1936

else

if (c=='

(') //

如果是左括號,直接進棧

3743

else

if (c=='

)') //

如果是右括號,匹配左括號,把兩者之間的棧內符號全部彈出

4452

else

if (top->dat=='-'

)56else

if (top->dat=='*'

)60else

if (top->dat=='/'

)6465 top=top->next;

66free

(s);67}

68 s=top;

69 top=top->next;

70free

(s);71}

72else

//否則肯定是+-*/了

7383

else

//否則就把棧頂的符號一直彈出,直到彈到可以壓進去,然後壓進去(也就是說等於也不能壓進去)

8492

else

if (top->dat=='-'

)96else

if (top->dat=='*'

)100

else

if (top->dat=='/'

)104 top=top->next;

105free

(s);

106 b=tance(top->dat);

107}

108 s=newp;

109 s->dat=c;

110 s->next=top;

111 top=s;

112}

113}

114 c=getchar(); //

讀取下乙個字元

115}

116while (top->dat!='

@') //

讀完和還不算完,還要把棧內剩餘的所有符號挨個彈出

117123

else

if (top->dat=='-'

)127

else

if (top->dat=='*'

)131

else

if (top->dat=='/'

)135 top=top->next;

136free

(s);

137}

138139

140 printf("

%d\n

",calc[1

]);141

return0;

142 }

ok,會了一位數的,其他的也就是小case啦,如果想看完整的多位數的**,可以參看  棧的應用2——超級計算器(中綴與字尾表示式)c語言

棧的應用2 超級計算器(中綴與字尾表示式)C語言

輸入中綴表示式輸出結果 結果可以是小數,但輸入必須是整數 1 include2 include 需要兩個棧,乙個儲存結果,乙個儲存運算子 3 define newpc stype malloc sizeof stype 4 define newpi inttype malloc sizeof int...

棧應用 中綴轉字尾 字尾計算

中綴表示式 infix expression 即 平時生活中大家對於算式的書寫格式 eg 6 5 2 3 8 3 字尾表示式 post expression 即 把數字和運算子分開,把運算子的優先順序運算內涵到字尾式的數字和運算子的順序 中 故其 優點就是,沒有必要知道任何優先的規則 乙個運算子只對...

動態陣列 棧的應用 之中綴計算器

格式化表示式 public class infixcalculator private static string insertblanks string expression else return sb.tostring 執行結果 中綴表示式實現的簡易的計算器 操作符棧 數字棧 如果遇到數字 直...