zoukankan      html  css  js  c++  java
  • 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 << "
    由逆波兰表达式计算出的数值结果:  ";
        cout << postfix_value(post) << endl;
    
    
        return 0;
    }
    View Code

  • 相关阅读:
    IOS调试下载的demo出现说项目不能在什么的SDK调试
    IOS手势基本用法
    IOS没有服务器断怎么调试Push代码
    VS Tips (Advance part)
    [转]如何理解C runtime library (C运行时库)
    Use AQTime to find the bottleneck of program module
    [转]Reflection: Discovery and Execution
    如何禁止生成stack对象或heap对象
    VS Tips (Basic part)
    栈对象、堆对象、静态对象的比较
  • 原文地址:https://www.cnblogs.com/lmlyzxiao/p/5610336.html
Copyright © 2011-2022 走看看