# include & ltiostream & gt
# include & ltstdlib.h & gt
使用命名空間std
const int maxsize = 100;//用於將表達式的最大長度限制為100個字符。
void welcome();//歡迎模塊
char * input();//輸入模塊
布爾校驗(char string[]);//檢查模塊
char compare(char,char);//其中壹個運算模塊用於比較運算符優先級。
雙階梯計算(雙a,char b,雙c);//其中壹個運算模塊用於單個加減乘除運算。
double finalcalculate(char字符串[]);//總運算模塊用於計算輸入的表達式結果。
char輸出(雙回答);
結構OS堆棧{//運算符堆棧定義
char stack[maxsize];
int top
};
結構nsstack{ //操作數堆棧定義
雙棧[maxsize];
int top
};
模板& lt鍵入名稱T0 & gtvoid in stack(T0 & amp;S){ //堆棧的初始化模板
s . top =-1;
}
模板& lttypename T1,typename T2 >無效推送(t 1 & amp;s,T2 x){//堆棧壓制模板
if(s.top==maxsize-1)
cout & lt& lt”溢出”;
否則{
s . top++;
s . stack[s . top]= x;
}
}
模板& lt鍵入名稱T4 & gt;虛空波普(T4 & amp;S){ //堆棧模板
if(s.top==-1)
cout & lt& lt”下溢”;
其他
s . top-;
}
模板& lttypename T3 & gtgettop(T3 & amp;S){ //獲取棧頂元素模板
if(s.top==-1){
cout & lt& lt”下溢”;
返回0;
}
其他
return s . stack[s . top];
}
雙答;
void main(){
char表達式[maxsize];
bool legal
welcome();//執行歡迎函數
char go _ on = ' y//go_on用於判斷是否繼續執行程序,初始化為y,
While (go _ on =' y') {//go _ on為y,進入循環,壹次循環後其值會輸入到out函數中,用來決定是否繼續輸入其他表達式。
合法= 0;
而(!Legal){ //legal為0,進入表達式輸入和校驗循環。當legal為1,即輸入的表達式合法時,退出循環並執行計算。
strcpy(expression,input());//使用字符數組表達式保存輸入表達式。
legal=check(表達式);//用legal表示輸入的表達式是否合法,為1,否則為0。
}
answer=finalcalculate(表達式);//將計算結果賦給答案。
go _ on =輸出(答案);//輸出計算結果
}
返回;
}
/*下面是棧的初始化和基本操作的定義*/
//定義了棧的相關操作,定義了以下函數。
void歡迎(){
cout & lt& lt"歡迎使用,本程序是表達式求值的實現,可以輸入壹個包含四種運算的表達式(括號可以用)進行運算!"& lt& ltendl
}
char *input(){
char string[maxsize];char * str
str =字符串;
cout & lt& lt請輸入要計算的表達式,然後按“enter”確認
cin.getline(string,maxsize);//通過鍵盤輸入壹個表達式,不超過100個字符。
返回字符串;
}
布爾校驗(char string[]){
int ecode//錯誤代碼,用於指示錯誤的類型,方便用戶檢查輸入的錯誤。
int k=0,j = 0;//用來記錄括號的個數,判斷括號是否匹配。
bool legal = 1;
for(int I = 0;string[i]!='\0';i++){
if((string[0]-' 0 ' & lt;0 | | string[0]-' 9 ' & gt;0)& amp;& amp(string[0]!= '('){ legal = 0;ecode = 1;打破;}//以數字和除“(”以外的字符開頭,錯誤。
如果(法律& amp& amp(string[I]-' 0 ' & lt;0 | | string[I]-' 9 ' & gt;0)& amp;& ampstring[i]!= '+' & amp;& ampstring[i]!= '-' & amp;& ampstring[i]!= ' * ' & amp& ampstring[i]!= '/' & amp;& ampstring[i]!= '(' & amp;& ampstring[i]!=')'){
合法= 0;ecode = 2;打破;}//表達式包含非法字符,錯誤。
if(string[I]= = '(')k++;
if(string[I]= = ')')j++;
}
如果(法律& amp& ampj!= k){ legal = 0;ecode = 3;}//表達式中的括號不匹配,錯誤。
else if(法律& amp& amp(string[I-1]-' 0 ' & lt;0 | | string[I-1]-' 9 ' & gt;0)& amp;& ampstring[i-1]!= ')'){ legal = 0;ecode = 4;}//表達式的結尾不正確。
if(legal = = 0)cout & lt;& lt“您輸入的表達式不正確,請檢查並重新輸入!錯誤代碼: "
回歸合法;
}
//下面是操作模塊的定義。
Char compare(char a,char b){ //判斷運算符A和B的優先級,返回字符常量'
int p,q;///p,q,q用來表示字符A和b的操作優先級。
開關(a){
大小寫“;”:p = 0;打破;//設置“;”優先級為0。
case '(':case ')':p = 1;打破;//設置' (',')'優先級為1說明:實際優先級括號大於加減乘除。
大小寫'+':大小寫'-':p = 2;打破;//設置'+'和'-'為優先級2。這裏為了堆棧操作的方便,將其復位。
case“*”:case“/”:p = 3;打破;//設置' * ',/'優先級為3。
}
開關(b){
大小寫“;”:q = 0;打破;
case '(':case ')':q = 1;打破;
格'+':格'-':q = 2;打破;
case ' * ':case '/':q = 3;打破;
}
如果(p & gtq)返回“>”;//通過P和q比較A和B的優先級。
如果(p & ltq)返回' & lt';
if(p==q)返回' = ';
}
雙步長計算(double x,char y,double z){
開關(y) {
大小寫“+”:
返回z+x;
打破;
大小寫'-':
返回z-x;
打破;
大小寫' * ':
返回z * x;
打破;
案例“/”:
如果(x!=0) {
返回z/x;
打破;
}
其他
cout & lt& lt除法器為零,輸入錯誤
默認值:
返回0;
}
}
double final calculate(char string[]){
osstack os//定義char棧變量os,用來存放運算符。
nsstack ns//定義壹個雙棧變量ns來存儲操作數。
int I = 0;
double num = 0;//定義浮點數num保存臨時結算結果。
雙ns1,ns2char op//定義浮點數ns1、ns2和字符op,分別作為基本運算中的操作數和運算符。
char * p;//字符指針,用於在掃描時指向緊接在符號字符之後的數值字符,以便於將數值字符串轉換為int類型。
in stack(OS);//初始化運算符堆棧
in stack(ns);//初始化操作數堆棧
push(os,';');//將“;”推送運算符堆棧
while(string[i]!='\0'){//掃描輸入表達式,在掃描過程中針對各種情況做出適當的動作。
while(string[i]!= '+' & amp;& ampstring[i]!= '-' & amp;& ampstring[i]!= ' * ' & amp& ampstring[i]!= '/' & amp;& ampstring[i]!= '(' & amp;& ampstring[i]!=')'){
p = & ampstring[I];//如果當前元素是壹個數字
num = atof(p);//將連續的數字字符轉換成壹個數字。
push(ns,num);//並行推入操作數堆棧
打破;}
對於(我;string[I]& gt;= 48 & amp& ampstring[I]& lt;=57;)i++;//當前字符為數字字符時,跳過所有連續的數字字符;
while(string[I]= = '+' | | string[I]= = '-' | | string[I]= = ' * ' | | string[I]= = '/' | | string[I]= = '(' | | string[I]= = ')' | | string[I]= = ';'){//確定當前元素和堆疊元素是否為運算符。
Switch (compare (string [I],gettop(OS)){//比較當前運算符和棧頂運算符的優先級。
大小寫“>”://當前操作員具有高優先級。
if(string[I]= = ')'){ i++;打破;}//且當前運算符優於“)”,表示棧頂運算符為“;”,跳過,我遞增,掃描下壹個字符。
else{push(os,string[I]);i++;打破;}//當前運算符不是“)”,優先級高。它被放入堆棧,I遞增。掃描下壹個字符。
Case'=': //當前運算符與棧頂運算符具有相同的優先級。
if(string[i]=='('){push(os,string[I]);i++;打破;}//如果當前操作符為' (',則將I加入堆棧,掃描下壹個字符。
else if(string[I]= = ')'){ pop(OS);i++;打破;}//如果當前操作符是')',說明棧頂操作符是' (',I被彈出後會自動遞增,掃描下壹個字符。
else { ns 1 = gettop(ns);//如果當前運算符是加減乘除,則會執行壹個基本運算。
pop(ns);//取操作數棧頂的兩個元素。
NS2 = gettop(ns);//執行基本運算並將這兩個元素推出堆棧的操作數。
pop(ns);
op = gettop(OS);//以運算操作符棧的頂層元素作為基本運算的操作符,
pop(OS);//並使其退出堆棧
num=stepcalculate(ns1,op,NS2);
push(ns,num);打破;}//將運算結果壓入操作數堆棧。
大小寫' & lt'://當前運算符的優先級小於頂層運算符的優先級。
if(string[i]=='('){push(os,string[I]);i++;打破;}//如果當前操作符是“(”,由於其實際優先級更高,應該放入堆棧。
else { ns 1 = gettop(ns);//如果是其他,會執行壹個基本操作。
pop(ns);//取操作數棧頂的兩個元素。
NS2 = gettop(ns);//執行基本運算並將這兩個元素推出堆棧的操作數。
pop(ns);
op = gettop(OS);//以運算操作符棧的頂層元素作為基本運算的操作符,
pop(OS);//並使其退出堆棧
num=stepcalculate(ns1,op,NS2);
push(ns,num);打破;}//將運算結果壓入操作數堆棧。
} char x = gettop(OS);
} }//表達式已被掃描;
而(ns.top!=0){ //如果表達式掃描後操作數棧頂地址不為零,說明計算還沒有結束,操作符棧中元素的優先級從上到下遞減。
ns 1 = gettop(ns);//循環執行基本操作,直到操作數堆棧的頂部地址不為零。操作數取自操作數堆棧的前兩個元素。
pop(ns);//取出後,退出堆棧
NS2 = gettop(ns);
pop(ns);
op = gettop(OS);//將運算符作為運算符堆棧的頂部元素
pop(OS);//獲取操作符並退出堆棧。
num=stepcalculate(ns1,op,NS2);
push(ns,num);}//將運算結果壓入操作數堆棧。
返回gettop(ns);//結束計算,返回最終結果。
}
字符輸出(雙重答案){
char go _ on
cout & lt& lt"計算結果是:"
cout & lt& lt按“Y”鍵繼續,按其他鍵退出程序,然後按“Enter”鍵確認。endl//壹個操作完成
CIN & gt;& gt繼續;
返回go _ on//給go_on賦值,選擇是否對其他表達式求值。
}