資料結構棧實現四則運算
阿新 • • 發佈:2019-02-17
例如,計算9+(3-1)*3+8/2
思路:通過棧來實現上述元素,我們一般稱上述表示式為中綴表示式,我們首先要將其轉換為字尾表示式,因為中綴表示式不利於計算機運算。
上程式碼:
演算法思路:
對字串中的內容,遇到數字就輸出,遇到符號則與棧頂元素比較優先順序,若低,則將棧頂元素彈棧,若高,則壓棧。若為右括號,則連續輸出,直到遇到左括號,這輸出的就是字尾表示式
其中isp()和icp()這兩個函式是對於優先順序的規定,在下一段程式碼中有它們的定義
void postfix(){
stack<char> s;
char y;
// s.makeEmpty();
s.push('#');
char ch[20]="9+(3-1)*3+8/2";
for(int i=0;i<13;i++){
if(isdigit(ch[i]))
cout<<ch[i];
else if(ch[i]==')'){
// cout<<ch[i]<<endl;
while(!(s.empty())&&(y=s.top())!='('){
cout<<y;
s.pop();
}
if (!s.empty())
s.pop();
}
else{
while(!s.empty()&&isp(y=s.top())>icp(ch[i])){
cout<<y;
s.pop();
}
s.push(ch[i]);
}
}
while(!s.empty()){
cout<<s.top();
s.pop();
}
}
有了字尾表示式,我們需要的是計算,我們做的是,遇數字壓棧,與符號則彈出前兩個數進行計算,將結果入棧。
#include<cmath>
#include<stack>
#include<iostream>
using namespace std;
int isp(char ch){
switch(ch){
case '#':
return 0;
case '(':
return 1;
case '^':
return 7;
case '*':
case '/':
case '%':
return 5;
case '+':
case '-':
return 3;
case ')':
return 8;
}
}
int icp(char ch){
switch(ch){
case '#':
return 0;
case '(':
return 8;
case '^':
return 6;
case '*':
case '/':
case '%':
return 4;
case '+':
case '-':
return 3;
case ')':
return 1;
}
}
class Calculator{
public:
Calculator(){}
double Run();
void Clear();
private:
void AddOperand(double value);
bool Get2Operands(double &left,double &right);
void DoOperator(char op);
stack<double> s;
};
void Calculator::AddOperand(double value){
s.push(value);
}
void Calculator::Clear(){
}
bool Calculator::Get2Operands(double &left,double &right){
if(s.empty()){
cerr<<"Missing Operands!"<<endl;
return false;
}
right = s.top();
s.pop();
if(s.empty()){
cerr<<"Missing Operands!"<<endl;
return false;
}
left = s.top();
s.pop();
return true;
}
void Calculator::DoOperator(char op){
double left,right;
bool result;
result = Get2Operands(left,right);
if(result==true){
switch(op){
case '+':
s.push(left+right);
break;
case '-':
s.push(left-right);
break;
case '*':
s.push(left*right);
break;
case '/':
if(abs(right)<=1E-6){
cerr<<"Divide By 0"<<endl;
Clear();
}
else
s.push(left/right);
break;
/* case '^':
s.push(left^right);
break;*/
}
}
else{
Clear();
}
}
double Calculator::Run(){
char ch;
double newoperand,ret;
while(cin>>ch,ch!='='){
switch( ch ) {
case '+':
case '-':
case '*':
case '/':
case '^':
DoOperator(ch);
break;
default:
cin.putback(ch);
cin >> newoperand;
AddOperand(newoperand);
break;
}
}
ret = s.top();
s.pop();
return ret;
}
int main(){
// postfix();
Calculator c;
double ans = c.Run();
cout<<ans;
return 0;
}