CSUFT 编译原理实验三 中缀表达式转逆波兰表达式求值

下面代码是完整版的 加入了单目减运算(即'-'负号 代码中用@符号代替)、浮点数运算、乘方运算。

要用自己写的模板化代码可以参考下面链接 http://blog.csdn.net/geekcoder/article/details/6829386

 

#include <iostream>
#include <cstdio>
#include <stack>
#include <cmath>

using namespace std;


bool isOperator(char op)
{
    switch(op)
    {
    case '+':
    case '-':
    case '*':
    case '/':
    case '^':
    case '@':
        return 1;
    default :
        return 0;
    }
}


int priority(char op)
{
    switch(op)
    {
    case '#':
        return -1;
    case '(':
        return 0;
    case '+':
    case '-':
        return 1;
    case '*':
    case '/':
        return 2;
    case '^':
        return 3;
    case '@':
        return 4;
    default :
        return -1;
    }
}
//   把中缀表达式转换为后缀表达式,返回后缀表达式的长度(包括空格)
void postfix(char pre[] ,char post[],int &n)
{
    int i = 0 ,j=0;
    stack<char>st;
         // 初始化存储操作符的栈

    st.push('#');    // 首先把结束标志‘#’放入栈底

    while(pre[i]!='#')
    {
        if((pre[i]>='0' && pre[i] <='9')||pre[i] =='.') // 遇到数字和小数点直接写入后缀表达式
        {
            post[j++] = pre[i];
            n++;
        }
        else if (pre[i]=='(')   // 遇到“(”不用比较直接入栈
            st.push(pre[i]);
        else if(pre[i] ==')')  // 遇到右括号将其对应左括号后的操作符(操作符栈中的)全部写入后缀表达式
        {
            while(st.top()!='(')
            {
                char t = st.top();
                st.pop();
                post[j++] = t;
                n++;
            }
            st.pop(); // 将“(”出栈,后缀表达式中不含小括号
        }
        else if (isOperator(pre[i]))
        {
            post[j++] = ' '; // 用空格分开操作数(
            n++;
            while(priority(pre[i]) <= priority(st.top()))
            {
                // 当前的操作符小于等于栈顶操作符的优先级时,将栈顶操作符写入到后缀表达式,重复此过程
                char t = st.top();
                st.pop();
                post[j++] = t;

                n++;
            }

            st.push(pre[i]); // 当前操作符优先级大于栈顶操作符的优先级,将该操作符入栈
        }

        i++;
    }
    while(!st.empty()) // 将所有的操作符加入后缀表达式
    {
        post[j++] = st.top();
        st.pop();
        n++;
    }
}

double read(char str[],int *i)
{
    double x=0.0;
    int k = 0;
    while(str[*i] >='0' && str[*i]<='9')  // 处理整数部分
    {
        x = x*10+(str[*i]-'0');
        (*i)++;
    }

    if(str[*i]=='.') // 处理小数部分
    {
        (*i)++;
        while(str[*i] >= '0'&&str[*i] <='9')
        {
            x = x * 10 + (str[*i]-'0');
            (*i)++;
            k++;
        }
    }
    while(k!=0)
    {
        x /= 10.0;
        k--;
    }

    return x;
}

double postfix_value(char post[])
{
    stack<double>st;    // 操作数栈


    int i=0 ;
    double x1,x2;

    while(post[i] !='#')
    {
        if(post[i] >='0' && post[i] <='9')
            st.push(read(post,&i));
        else if(post[i] == ' ')
            i++;
        else if (post[i] =='+')
        {
            x2 = st.top();
            st.pop();
            x1 = st.top();
            st.pop();
            st.push(x1+x2);
            i++;
        }
        else if (post[i] =='-')
        {
            x2 = st.top();
            st.pop();
            x1 = st.top();
            st.pop();
            st.push(x1-x2);
            i++;
        }
        else if (post[i] =='*')
        {
            x2 = st.top();
            st.pop();
            x1 = st.top();
            st.pop();
            st.push(x1*x2);
            i++;
        }
        else if (post[i] =='/')
        {
            x2 = st.top();
            st.pop();
            x1 = st.top();
            st.pop();
            st.push(x1/x2);
            i++;
        }
         else if (post[i] =='^') //乘方运算符
        {
            x2 = st.top();
            st.pop();
            x1 = st.top();
            st.pop();
            double t = pow(x1,x2);
            st.push(t);
            i++;
        }
         else if (post[i] =='@') //单目-运算符用@代替

        {
            x2 = st.top();
            st.pop();
            x2 = 0-x2;
            st.push(x2);
            i++;
        }
    }
    return st.top();
}

int  main()
{
    stack<int>st ;


    char exp[100];
    cout << "输入表达式(中缀,以#结束):";
    cin >> exp;

    char post[100] ;


    int n =0;           // 返回后缀表达式的长度
    postfix(exp,post,n);
    cout <<"逆波兰表达式为:";
    for( int i =0 ;i < n ;i++)
        cout << post[i] ;

    cout << "\n由逆波兰表达式计算出的数值结果:  ";
    cout << postfix_value(post) << endl;


    return 0;
}
View Code

 

posted @ 2016-06-23 12:48  lmlyzxiao  阅读(563)  评论(0编辑  收藏  举报