用栈解决四则运算问题
分享一下我老師大神的人工智能教程!零基礎(chǔ),通俗易懂!http://blog.csdn.net/jiangjunshow
也歡迎大家轉(zhuǎn)載本篇文章。分享知識(shí),造福人民,實(shí)現(xiàn)我們中華民族偉大復(fù)興!
本文章的解決方法參考了《大話數(shù)據(jù)結(jié)構(gòu)》中關(guān)于棧的應(yīng)用介紹
值得注意的是,書中關(guān)于中綴表達(dá)式轉(zhuǎn)后綴的講解中不盡清楚。本人也在這里花了點(diǎn)時(shí)間進(jìn)行推敲錯(cuò)誤的原因,也在網(wǎng)上搜到了這篇文章,比較好地介紹了中綴轉(zhuǎn)后綴的的規(guī)則
原理:
用計(jì)算機(jī)求解四則運(yùn)算,可以使用棧。因?yàn)?strong>棧的“先進(jìn)后出”的特性正好滿足了能通過后綴表達(dá)式去計(jì)算出四則運(yùn)算式子的結(jié)果。而后綴表達(dá)式的轉(zhuǎn)化也能使用棧對(duì)中綴表達(dá)式進(jìn)行操作從而轉(zhuǎn)化。明顯地,由中綴表達(dá)式-》后綴表達(dá)式, 后綴表達(dá)式-》式子結(jié)果。 都需要使用到棧。所以編碼實(shí)現(xiàn)中,我們著重的是實(shí)現(xiàn)這兩個(gè)過程的函數(shù)(infix_to_suffix()、suffix_to_result())
注意:
測試數(shù)據(jù)
- 每個(gè)數(shù)可以是只達(dá)個(gè)位的數(shù),也可以達(dá)十位以上的數(shù)
- 可以是負(fù)數(shù)或正數(shù)(負(fù)數(shù)需在兩邊添加括號(hào))
- 括號(hào)內(nèi)能存在多個(gè)括號(hào),例:( ( 2 + 3 ) + ( 4 + 5 ) + ( ( 6 + 7 ) + 8 ) )
實(shí)現(xiàn)
- 定義了一個(gè)全局table用來存儲(chǔ)各個(gè)運(yùn)算符的優(yōu)先級(jí)。 + - 等優(yōu)先級(jí),* / 等優(yōu)先級(jí), ()不存在優(yōu)先級(jí)(這里主要為了代碼實(shí)現(xiàn)而取消其優(yōu)先級(jí))
- 設(shè)置了一個(gè) priority 變量進(jìn)行存儲(chǔ)棧頂元素的優(yōu)先級(jí),這在中綴轉(zhuǎn)后綴的時(shí)候被使用到,并在每次的壓棧出棧后,都須對(duì)新的棧頂元素進(jìn)行記錄其優(yōu)先級(jí)
- 在中綴轉(zhuǎn)后綴的函數(shù)中,主要包含這幾部分:1. 遇到數(shù)字直接輸出,然后continue ?2.左括號(hào)直接壓棧,然后continue?3.右括號(hào)則將將棧中在左括號(hào)以上的所有運(yùn)算符彈出,然后continue ?4. 若是運(yùn)算符,判斷是否優(yōu)先級(jí)比棧頂元素小或相等,若是,則將在左括號(hào)前或優(yōu)先級(jí)大于或等于待壓棧元素的棧中元素出棧。若不是,則正常壓棧,正常壓棧過程中需判斷是否負(fù)數(shù) ?5.遍歷中綴表達(dá)式結(jié)束后,將棧中還存在的所有元素進(jìn)行出棧
const int MAXSIZE = 100;//棧的數(shù)據(jù)結(jié)構(gòu)typedef struct {?int??? data[MAXSIZE];?int??? top;} Stack;int??? table[] = {0,0,2,1,0,1,0,2};//查詢運(yùn)算符優(yōu)先級(jí)表//函數(shù)說明:將中綴表達(dá)式轉(zhuǎn)換為后綴表達(dá)式//參數(shù)說明://sta:??? 轉(zhuǎn)換過程需使用的棧空間//infix:? 待轉(zhuǎn)換的中綴表達(dá)式//suffix: 存儲(chǔ)轉(zhuǎn)換后的后綴表達(dá)式//length: 記錄后綴表達(dá)式的長度void infix_to_suffix(Stack *sta, char *infix, int *suffix, int *length);//函數(shù)說明:將后綴表達(dá)式轉(zhuǎn)換為結(jié)果直接返回//參數(shù)說明://sta:??? 轉(zhuǎn)換過程需使用的棧空間//suffix: 存儲(chǔ)轉(zhuǎn)換后的后綴表達(dá)式//length: 記錄后綴表達(dá)式的長度int? suffix_to_result(Stack *sta, int *suffix, int length);void init(Stack *sta);//棧空間初始化int main(){?//這里將標(biāo)準(zhǔn)輸入輸出流重定向到文件中//?freopen("in.txt", "r", stdin);//?freopen("out.txt", "w", stdout);?Stack???? sta;?int?????? length;?int?????? result;???????? //接受后綴表達(dá)式轉(zhuǎn)換的結(jié)果?int?????? sstr[MAXSIZE];? //存儲(chǔ)后綴表達(dá)式?char????? istr[MAXSIZE];? //存儲(chǔ)中綴表達(dá)式?printf("請(qǐng)輸入以 + - * / 組成的四則運(yùn)算\n(注意負(fù)數(shù)需要在兩旁添加上括號(hào))\n");?scanf("%s", istr);?init(&sta); //對(duì)棧空間初始化?infix_to_suffix(&sta, istr, sstr, &length);?init(&sta); //再次對(duì)棧空間初始化?result = suffix_to_result(&sta, sstr, length);?printf("%d\n", result);//?fclose(stdin);//?fclose(stdout);?return??? 0;}void infix_to_suffix(Stack *sta, char *infix, int *suffix, int *length){?int??? i;????//循環(huán)變量?int??? b = 0;???//當(dāng)數(shù)字是十位或以上的時(shí)候進(jìn)行記錄?int??? j = 0;???//suffix數(shù)組的下標(biāo)?int??? priority = 0;?//記錄棧頂元素的優(yōu)先級(jí)?//for循環(huán)的第三表達(dá)式不進(jìn)行i++,將其放在每一次的壓棧后或直接輸出到suffix進(jìn)行i++?for (i = 0; i < strlen(infix); )?{??//如果是數(shù)字的話,直接放在suffix中,然后continue??if (infix[i] >= '0' && infix[i] <= '9')??{???b = 0;??//謹(jǐn)記每次都需重新賦值為零!???while (infix[i] >= '0' && infix[i] <= '9')???{????b = b * 10 + (infix[i] - '0');????i++;???}???suffix[j] = b;???j++;???continue;??}??//如果是右括號(hào)的話,將棧中在左括號(hào)以上的所有運(yùn)算符彈出,然后continue??if (infix[i] == 41)??{???while (sta->data[sta->top] != 40)???{????suffix[j] = sta->data[sta->top];????sta->data[sta->top] = 0;????sta->top--;????j++;???}???sta->data[sta->top] = 0;???sta->top--;???//注意出棧后,須將新的棧頂元素的優(yōu)先級(jí)記錄下來???priority = table[sta->data[sta->top] % 10];???i++;???continue;??}??//如果是左括號(hào)的話,直接壓棧??if (infix[i] == 40)??{???sta->top++;???sta->data[sta->top] = infix[i];???//注意壓棧后,須將新的棧頂元素的優(yōu)先級(jí)記錄下來???priority = table[sta->data[sta->top] % 10];???i++;???continue;??}??//如果只是普通的運(yùn)算符,則壓棧??if (infix[i] >= 42 && infix[i] <= 47)??{???//首先比較棧頂元素的優(yōu)先級(jí)是否比入棧元素優(yōu)先級(jí)要大???//如果是大于的話,則從棧頂將元素依次出棧后,把待入棧的元素壓棧???if (priority >= table[infix[i] % 10])???{????while (priority >= table[infix[i] % 10] && sta->data[sta->top] != 40)????{?????suffix[j] = sta->data[sta->top];?????sta->data[sta->top] = 0;?????sta->top--;?????//注意每次的出棧后,須將新的棧頂元素的優(yōu)先級(jí)記錄下來用作比較?????priority = table[sta->data[sta->top] % 10];?????j++;????}????sta->top++;????sta->data[sta->top] = infix[i];????//注意壓棧后,須將新的棧頂元素的優(yōu)先級(jí)記錄下來????priority = table[sta->data[sta->top] % 10];????i++;???}???else ???{????//這里主要處理負(fù)數(shù)的提取????if (infix[i] == 45 && sta->data[sta->top] == 40)????{?????b = 0;?????while (infix[i+1] >= '0' && infix[i+1] <= '9')?????{??????b = b * 10 + (infix[i+1] - '0');??????i++;?????}?????suffix[j] = b * -1;?????sta->data[sta->top] = 0;?????sta->top--;?????j++;?????i += 2;?????priority = table[sta->data[sta->top] % 10];?????continue;????}????sta->top++;????sta->data[sta->top] = infix[i];????//注意壓棧后,須將新的棧頂元素的優(yōu)先級(jí)記錄下來????priority = table[sta->data[sta->top] % 10];????????i++;???}??}?}?//把棧中還存在的元素進(jìn)行彈出?while (sta->top != -1)?{??suffix[j] = sta->data[sta->top];??sta->top--;??j++;?}?*length = j;}int suffix_to_result(Stack *sta, int *suffix, int length){?int??? i;?int??? j;?int??? result = 0;?for (i = 0; i < length; i++)?{??//循環(huán)遍歷后綴表達(dá)式,數(shù)字就直接壓棧,運(yùn)算符就取棧頂兩個(gè)元素出來計(jì)算,并將結(jié)果壓棧??switch (suffix[i])??{??case 42:???result = sta->data[sta->top - 1] * sta->data[sta->top];???sta->top -= 1;???sta->data[sta->top] = result;???break;??case 43:???result = sta->data[sta->top - 1] + sta->data[sta->top];???sta->top -= 1;???sta->data[sta->top] = result;???break;??case 45:???result = sta->data[sta->top - 1] - sta->data[sta->top];???sta->top -= 1;???sta->data[sta->top] = result;???break;??case 47:???result = sta->data[sta->top - 1] / sta->data[sta->top];???sta->top -= 1;???sta->data[sta->top] = result;???break;??default:???sta->top++;???sta->data[sta->top] = suffix[i];???break;??}?}?return?? result;}//初始化棧空間void init(Stack *sta){?int???? i;?for (i = 0; i < MAXSIZE; i++)?{??sta->data[i] = 0;?}?sta->top = -1;}
???????????
給我老師的人工智能教程打call!http://blog.csdn.net/jiangjunshow
總結(jié)
以上是生活随笔為你收集整理的用栈解决四则运算问题的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: c语言必背数组函数100代码,C语言必背
- 下一篇: 第十三届蓝桥杯2022各组完整真题(可评