這裡要學的程式主要用來實現乙個功能——輸入表示式輸出結果,也就是乙個計算器。效果如下:
這個程式主要有兩個步驟: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 #include3ok,會了一位數的,其他的也就是小case啦,如果想看完整的多位數的**,可以參看 棧的應用2——超級計算器(中綴與字尾表示式)c語言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 }
棧的應用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 執行結果 中綴表示式實現的簡易的計算器 操作符棧 數字棧 如果遇到數字 直...