C++表達式求值詳解
一.細節(jié)處理:
1.注意負數(shù) 因此要進行字符串預處理
string format(string str)
{
int len = str.length();
for (int i = 0; i < len; i++)
{
if (str[i] == '-')
{
if (i == 0) { str.insert(0, 1, '0'); }//處理-3*2+1情況
else if (str[i - 1]=='(') { str.insert(i, 1, '0'); }//處理(-3*4+1)情況
}
}
return str;
}
2.考慮除數(shù)為0
case '/':
if (0 != y) { res = x / y; }
else { cout << "非法表達式"; return -1; }
break;
3.原字符串再加上一個定界符 '#'
str=str+'#'
4.優(yōu)先級:
1."("未入棧前為3 入棧后為0 2.”)"和"#"為0 3.”+" "-"為1 4.”*"和"/"為2
二.知識要點:
中綴表達式轉(zhuǎn)為后綴表達式
1. 首先設置存儲運算符和存儲操作數(shù)兩個棧 即Symbol[N]和Num[N]且分別對應top2,top1
top1=-1 Symbol[0]='#' //運算符棧設置定界符 top2=0
2.入棧和出棧的規(guī)則 字符串為str
一.若str[i]>='0&&str[i]<='9',則入操作數(shù)棧并繼續(xù)掃描以一個字符 即Num[++top1]=str[i++]-'0';
二.否則 將當前字符str1與運算符棧的棧頂元素str2進行優(yōu)先級比較 ,自寫比較函數(shù)
例如: str1==‘+' 則若str2==# ,(,) 則返回1 說明str1比str2優(yōu)先級高
1. 此時若str1優(yōu)先級大于str2 則將str1入運算符棧并繼續(xù)掃描 即 Symbol[++top2]=str[i++]
2.優(yōu)先級相等則返回0 此時將運算符棧頂元素彈出,并繼續(xù)掃描下一個字符即 top2-- i++
3.若str1優(yōu)先級小于str2返回-1,此時將運算符棧頂元素彈出 即op=Symbol[top2--]
并彈出操作數(shù)棧的兩個元素 即y=Num[top1--],x=Num[top1--] 之后進行計算操作
三.最后 return Num[top1]
三.完整源碼:
#define _CRT_SECURE_NO_WARNINGS
#include<bits/stdc++.h>
using namespace std;
class Expression
{
public:
Expression(string str);
~Expression();
int Compute();
private:
int Comp(char str1, char str2);
string str1;
};
Expression::Expression(string str)
{
this->str1 = str + '#';//以定界符開頭
}
Expression :: ~Expression() {}
//將中綴表達轉(zhuǎn)為后綴表達
int Expression::Compute()
{
int Num[100], Symbol[100];//定義存操作數(shù)和運算符的兩個棧
int i, k, x, y, res;
char op;
Symbol[0] = '#';
int top1 = -1, top2 = 0;
for (i = 0; str1[i] != '\0';)
{
if (str1[i] >= '0' && str1[i] <= '9') { Num[++top1] = str1[i++] - '0'; }
else {//非操作數(shù)就比較運算符優(yōu)先級
int cmp = Comp(str1[i], Symbol[top2]);
if (cmp == 1) { Symbol[++top2] = str1[i++]; }//將運算符入棧 并接著掃描下一個字符
else if (cmp == 0) { --top2; i++; }//優(yōu)先級相等 彈棧 并接著掃描下一個字符
else {//優(yōu)先級低 繼續(xù)處理當前運算符
y = Num[top1--];//后面的數(shù)要先彈出來 才不會算反
x= Num[top1--];
op = Symbol[top2--];
switch (op)
{
case '+':
res = x + y;//將運算結(jié)果入棧
break;
case '-':
res = x - y;
break;
case '*':
res = x * y;
break;
case '/':
if (0 != y) { res = x / y; }
else { cout << "非法表達式"; return -1; }
break;
default:break;
}
Num[++top1] = res;
}
}
}
return Num[top1];
}
string format(string str)
{
int len = str.length();
for (int i = 0; i < len; i++)
{
if (str[i] == '-')
{
if (i == 0) { str.insert(0, 1, '0'); }//處理-3*2+1情況
else if (str[i - 1]=='(') { str.insert(i, 1, '0'); }//處理(-3*4+1)情況
}
}
return str;
}
int main()
{
string str;
int n = 3;
while (n--)
{
cout << "請輸入一個表達式: " << endl;
cin >> str;
str = format(str);
Expression E(str);
int result = E.Compute();
cout << "表達式的值的是: " << result << endl;
}
return 0;
}
int Expression::Comp(char str1, char str2)//當前字符元素和棧頂運算符優(yōu)先級比較
{
//1代表 str1優(yōu)先級大于str2 0 代表相等 -1代表小于
switch (str1)
{
case'+':case'-':
if (str2 == '#'||str2==')'||str2=='(') { return 1; }//左括號入隊列后優(yōu)先級變?yōu)?
else { return -1; }
break;
case'*':case'/':
if (str2 == '*' || str2 == '/') { return -1; }
else { return 1; }
break;
case'(':
return 1;
break;
case')':
if (str2 == '(') { return 0; }
else if(str2 == '#') { return 1; }
else { return -1; }
break;
case'#':
if (str2 == '#') { return 0; }
else { return -1; }
break;
default: break;
}
}
四.測試結(jié)果:

總結(jié)
本篇文章就到這里了,希望能夠給你帶來幫助,也希望您能夠多多關注腳本之家的更多內(nèi)容!
相關文章
c++中將二維數(shù)組元素變換為逆向存放的實現(xiàn)代碼
編程將一個二維數(shù)組元素變換為逆向存放,即按元素在內(nèi)存中的物理排列位置,第一個元素變成倒數(shù)第一個元素,第二個元素變成倒數(shù)第二個元素,依此類推2020-11-11
C++ 數(shù)據(jù)結(jié)構鏈表的實現(xiàn)代碼
這篇文章主要介紹了C++ 數(shù)據(jù)結(jié)構鏈表的實現(xiàn)代碼的相關資料,需要的朋友可以參考下2017-01-01
visual studio code 編譯運行html css js文件的教程
這篇文章主要介紹了visual studio code 如何編譯運行html css js文件,本文通過圖文實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-03-03

