一.中綴轉後綴
1.遇到操作數:直接輸出(添加到後綴表達式中)
2.棧爲空時,遇到運算符,直接入棧
3.遇到左括號:將其入棧
4.遇到右括號:執行出棧操作,並將出棧的元素輸出,直到彈出棧的是左括號,左括號不輸出。
5.遇到其他運算符:例如加減乘除:彈出所有優先級大於或者等於該運算符的棧頂元素,然後將該運算符入棧。
6.最終將棧中的元素依次出棧,輸出。
二.由後綴表達式得到表達式樹
三.對表達式樹的根節點調用cal()虛函數就能算出表達式的值
代碼
#include<iostream>
#include<string>
#include<map>
#include<stack>
using namespace std;
map<char, int> m{
{'*', 3}, {'/', 3},
{'+', 4}, {'-', 4},
{'(', 99}
};//定義優先級
class node
{
public:
virtual double cal() const = 0;
virtual ~node () {}
};
class numnode : public node
{
public:
numnode(double d):number(d){}
virtual double cal() const;
private:
double number;
};
class binarynode : public node
{
protected:
node* _left;
node* _right;
public:
binarynode(node* left, node* right):_left(left),_right(right){}
~binarynode();
};
class addnode : public binarynode
{
public:
addnode(node* left, node* right):binarynode(left, right){};
virtual double cal() const;
};
class mutinode : public binarynode
{
public:
mutinode(node* left, node* right):binarynode(left, right){};
virtual double cal() const;
};
inline double numnode::cal() const
{
return number;
}
binarynode::~binarynode()
{
delete _left;
delete _right;
}
double addnode::cal() const
{
return _left->cal() + _right->cal();
}
double mutinode::cal() const
{
return _left->cal() * _right->cal();
}
string suffix(const string& str) //得到後綴表達式
{
stack<char> sta;
string ret;
for(int i=0; i<str.size(); i++)
{
if( str[i]=='.' || (str[i]>='0' && str[i]<='9') )
{
ret += str[i];
}
else
{
if(ret.back() != ' ')ret += " " ;
if( sta.empty() || str[i]=='(' )
sta.push(str[i]);
else if(str[i] == ')')
{
while(sta.top()!='(')
{
ret.push_back(sta.top());
ret.push_back(' ');
sta.pop();
}
sta.pop();
}
else
{
while( !sta.empty() && m[str[i]]>=m[sta.top()] )
{
ret = ret + sta.top()+" ";
sta.pop();
}
sta.push(str[i]);
}
}
//cout<<i+1<<" "<<ret<<endl;
}
ret += " ";//確保每個數後邊都有個空格
while(!sta.empty())
{
ret = ret + sta.top()+" ";
sta.pop();
}
return ret;
}
node* suffix_tree(const string& str)//生成後綴表達式樹
{
stack<node*> sta;
string temp;
node* left;
node* right;
for(int i=0; i<str.size(); i++)
{
//cout<<i<<endl;
if( str[i]=='.' || (str[i]>='0' && str[i]<='9') )
{
temp += str[i];//cout<<"temp"<<temp<<endl;
}
else if(str[i]==' ' && str[i-1]>='0' && str[i-1]<='9' )
{
double d = stod(temp);
node *pnode = new numnode(d);
sta.push(pnode);
temp = "";
}
else if(str[i]==' ')
continue;
else switch(str[i])
{
case '+':
right = sta.top();
sta.pop();
left = sta.top();
sta.pop();
sta.push(new addnode(left,right));
break;
case '*':
right = sta.top();
sta.pop();
left = sta.top();
sta.pop();
sta.push(new mutinode(left,right));
break;
}
}
return sta.top();
}
int main()
{
string temp = "11.0+22*33+(44.0*55+66)*77";
cout<<"11.0+22*33+(44.0*55+66)*77的後綴表達式:";//11.0 22 33 * + 44.0 55 * 66 + 77 * +
string sur = suffix(temp);
cout<<sur<<endl;
node* root = suffix_tree(sur);
double x = root->cal();
cout << x << endl;//192159
delete root;
}
一.中綴轉後綴
二.由後綴直接得到結果
#include<iostream>
#include<string>
#include<map>
#include<stack>
using namespace std;
map<char, int> m{
{'*', 3}, {'/', 3},
{'+', 4}, {'-', 4},
{'(', 99}
};
string suffix(const string& str)
{
stack<char> sta;
string ret;
for(int i=0; i<str.size(); i++)
{
if(str[i]>='0' && str[i]<='9')
{
ret += str[i];
}
else
{
if(ret.back() != ' ')ret += " " ;
if( sta.empty() || str[i]=='(' )
sta.push(str[i]);
else if(str[i] == ')')
{
while(sta.top()!='(')
{
ret = ret + sta.top()+" ";
sta.pop();
}
sta.pop();
}
else
{
while( !sta.empty() && m[str[i]]>=m[sta.top()] )
{
ret = ret + sta.top()+" ";
sta.pop();
}
sta.push(str[i]);
}
}
//cout<<i+1<<" "<<ret<<endl;
}
ret += " ";//確保每個數後邊都有個空格
while(!sta.empty())
{
ret = ret + sta.top()+" ";
sta.pop();
}
return ret;
}
int cal(const string &str)
{
stack<int> sta;
string temp;
int left = 0;
int right = 0;
for(int i=0; i<str.size(); i++)
{
//cout<<i<<endl;
if(str[i]>='0' && str[i]<='9')
{
temp += str[i];//cout<<"temp"<<temp<<endl;
}
else if(str[i]==' ' && str[i-1]>='0' && str[i-1]<='9' )
{
sta.push(stoi(temp));
temp = "";
}
else if(str[i]==' ')
continue;
else switch(str[i])
{
case '+':
right = sta.top();//cout<<"right"<<right<<endl;
sta.pop();
left = sta.top();//cout<<"left"<<left<<endl;
sta.pop();
sta.push(left+right);//cout<<"jia"<<sta.top() <<endl;
break;
case '*':
right = sta.top();//cout<<"right"<<right<<endl;
sta.pop();
left = sta.top();//cout<<"left"<<left<<endl;
sta.pop();
sta.push(left*right);//cout<<"cheng"<<sta.top() <<endl;
break;
}
}
return sta.top();
}
int main()
{
string temp = "11+22*33+(44*55+66)*77";
cout<<"11+22*33+(44*55+66)*77的後綴表達式:";//11 22 33 *+ 44 55 *66 + 77 *+
string sur = suffix(temp);
cout<<sur<<endl;
cout<<"表達式的和:";
int sum = cal(sur);
cout<<sum<<endl;
}
參考:http://www.cnblogs.com/Solstice/archive/2012/07/06/learncpp.html
http://www.relisoft.com/book/lang/poly/3tree.html