中缀转后缀

    一般的来说,通常意义的中缀转后缀可以通过栈来实现,关于这方面的算法可以自行百度,就不再赘述了。

    在这里,我使用上下文无关文法来实现中缀表达式转后缀表达式。如果需要计算,可以直接用栈对后缀表达式进行计算就行了。

    当然,并不是说用栈来实现的中缀转后缀不好,个人觉得,思路上好麻烦,远没有这个清晰

 

    首先,上下文无关文法(百度百科: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;
}


     感觉很清晰有木有。

       

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值