一般的来说,通常意义的中缀转后缀可以通过栈来实现,关于这方面的算法可以自行百度,就不再赘述了。
在这里,我使用上下文无关文法来实现中缀表达式转后缀表达式。如果需要计算,可以直接用栈对后缀表达式进行计算就行了。
当然,并不是说用栈来实现的中缀转后缀不好,个人觉得,思路上好麻烦,远没有这个清晰
首先,上下文无关文法(百度百科:http://baike.baidu.com/link?url=RaDL9NHs_e0pkrP6YvtONDDf2OGFLQQrM5klO7Lhm2erX9aSrk6KSqKGeFI4E5NX)具体在这儿就不介绍了。
对于中缀表达式,主要是 + - * / % ( ),可以写出如下的文法:
G -> num
| ( E )
E -> E + F
| E - F
| F
F -> F * G
| F / G
| F % G
| G
去左递归优化后的文法:
G -> num
| ( E )
E -> F E'
E'-> + F E'
| - F E'
| null
F -> G F'
F'-> * G F'
| / G F'
| % G F'
| null
对此,可以把代码写出来了
/***
中缀转后缀
Design by Klarkxy at 2014/02/08
***/
#include <iostream>
#include <string>
#include <sstream>
#include <vector>
#include <algorithm>
using namespace std;
class MidExpression
{
/*
G -> num
| ( E )
E -> F E'
E'-> + F E'
| - F E'
| null
F -> G F'
F'-> * G F'
| / G F'
| % G F'
| null
*/
public:
private:
vector<string>::iterator dex,_end;
vector<string> ans;
bool match(string);
void match_G();
void match_E();
void match_F();
void match_E_();
void match_F_();
public:
MidExpression(){}
int run(vector<string>);
};
string connect(vector<string> st)
{
string ret;
for (vector<string>::iterator i=st.begin();i!=st.end();i++)
ret+=*i+" ";
return ret;
}
template<class T>
string toString(T&x)
{
ostringstream sout;
sout << x;
return sout.str();
}
int toInt(string x)
{
int ret;
istringstream sin(x);
sin >> ret;
return ret;
}
bool MidExpression::match(string str)
{
if (dex!=_end&&*dex==str){dex++;return true;}
else return false;
}
/*
E -> F E'
*/void MidExpression::match_E()
{
match_F();match_E_();
}
/*
E'-> + F E'
| - F E'
| null
*/void MidExpression::match_E_()
{
if (match("+")){match_F();ans.push_back("+");match_E_();}
else if (match("-")){match_F();ans.push_back("-");match_E_();}
}
/*
F -> G F'
*/void MidExpression::match_F()
{
match_G();match_F_();
}
/*
F'-> * G F'
| / G F'
| % G F'
| null
*/void MidExpression::match_F_()
{
if (match("*")){match_G();ans.push_back("*");match_F_();}
else if (match("/")){match_G();ans.push_back("/");match_F_();}
else if (match("%")){match_G();ans.push_back("%");match_F_();}
}
/*
G -> num
| ( E )
*/void MidExpression::match_G()
{
if (dex!=_end&&isdigit((*dex)[0])){ans.push_back(*dex);dex++;}
else if (match("("))
{
match_E();
if (match(")"));
else throw string("Syntax Error!");
}else throw string("Syntax Error!");
}
int MidExpression::run(vector<string> st)
{
try
{
ans.clear();
dex=st.begin();_end=st.end();
match_E();
if (dex==_end)cout << connect(ans) << endl;
else throw string("Syntax Error!");
}catch(string err){cout << err;}
cout << endl;
}
vector<string> split(string str)
{
vector<string> ret;
for (string::iterator i=str.begin();i!=str.end();)
if (isdigit(*i))
{
string st;
for (;isdigit(*i);i++) st+=*i;
ret.push_back(st);
}else ret.push_back(toString(*i)),i++;
return ret;
}
int main()
{
string str;
MidExpression me;
while (cin >> str)
me.run(split(str));
return 0;
}
感觉很清晰有木有。