中綴表達式
我們平時寫的表達式稱爲中綴表達式。
eg: 1. 2 - 3*4 +5 2. 2* (3- 5) +7
正如上面的表達式,我們在計算的過程中,首先要注意運算符的優先級,其次要注意括號。 我們應如何判斷運算符的優先級以及如何進行運算。
後綴表達式
首先,我們可以將中綴表達式轉化爲後綴表達式(逆波蘭表達式),然後進行運算。如何將中綴表達式轉化爲後綴表達式呢?規則如下:
將上面的中綴表達式轉化爲後綴表達式:1. 2 3 4 * - 5 + 2. 2 3 - 5 * 7 +
後綴表達式如何進行計算
藉助棧,依次遍歷後綴表達式,當遇到操作數時,直接進行入棧。當遇到操作符時,彈出棧中的兩個元素,依次作爲右操作數和左操作數,將計算後的結果壓入棧中。最後棧中剩餘的元素,則爲表達式的值。
代碼實現:
#include<iostream>
#include<vector>
#include<string>
#include<stack>
using namespace std;
//判斷是操作符還是操作數
enum Cal_Type
{
OP_NUM,
OP_SYMBOL,
};
struct Cell
{
Cal_Type _type;//計算類型
int _value;
Cell(const Cal_Type& t, const int& x)
:_type(t)
,_value(x)
{}
};
class Calculator
{
public:
Calculator(const vector<int> &exp)
:_infix(exp)
{}
int Count()
{
Transition(); //將中綴表達式轉化爲後綴表達式
stack<int> num; //中間計算過程中的操作數
int n = _exp.size();
for(int i=0; i<n; ++i)
{
Cell cur = _exp[i];
if(cur._type == OP_NUM)
{
num.push(cur._value);
}
else if(cur._type == OP_SYMBOL)
{
int d2 = num.top(); //右操作數
num.pop();
int d1 = num.top(); //左操作數
num.pop();
int sum = 0;
switch(cur._value)
{
case '+':
{sum = d1+d2;}
break;
case '-':
{sum = d1-d2;}
break;
case '*':
{sum = d1*d2;}
break;
case '/':
{sum = d1/d2;}
break;
default:
break;
}
num.push(sum);
}
}
return num.top();
}
//判斷是否爲操作符
bool IsTypied(char op)
{
switch(op)
{
case '-':
case '+':
case '*':
case '/':
return true;
default:
return false;
break;
}
}
//確定操作符的優先級
int Priority(char op)
{
switch(op)
{
case '-':
case '+':
return 1;
case '*':
case '/':
return 2;
default:
break;
}
return -1;
}
//中綴轉後綴表達式
void Transition()
{
stack<int> tmp; //用於保存遇到‘(’時的運算符
for(int i=0; i<_infix.size(); ++i)
{
if((_infix[i]+48)>='0' && (_infix[i]+48)<='9')//當遇到數字時,直接插入後綴表達式中
{
Cell c(OP_NUM,_infix[i]);
_exp.push_back(c);
}
else if(_infix[i] == '(')
{
tmp.push(_infix[i]);
}
else if(_infix[i] == ')')
{
while(tmp.top() != '(')
{
_exp.push_back(Cell(OP_SYMBOL,tmp.top()));
tmp.pop();
}
tmp.pop();
}
else if(IsTypied(_infix[i])) //如果爲運算符,應該判斷優先級
{
if(tmp.empty() || Priority(_infix[i]) > Priority(tmp.top()))//如果tmp爲NULL的話,只需要判斷棧頂元素和_infix[i]的優先級
{
tmp.push(_infix[i]);
}
else
{
while(!tmp.empty() && Priority(_infix[i]) <= Priority(tmp.top()))
{
_exp.push_back(Cell(OP_SYMBOL,tmp.top()));
tmp.pop();
}
tmp.push(_infix[i]);
}
}
else
{
cout<<"輸入有誤"<<endl;
_exp.clear();
return ;
}
}
//如果tmp 不爲NULL的話,全部壓入_exp中
while(!tmp.empty())
{
_exp.push_back(Cell(OP_SYMBOL,tmp.top()));
tmp.pop();
}
}
private:
vector<int> _infix; //中綴表達式
vector<Cell> _exp; //後綴表達式
};
void Test()
{
int a[] = {2,'-',3,'*',4,'+',5};
vector<int> exp(a,a+sizeof(a)/sizeof(a[0]));
Calculator c(exp);
cout<<c.Count()<<endl;
}