• 逆波兰表达式计算(后缀表达式,中缀转后缀)


    /*
    后缀表达式计算
    
    中缀表达式转后缀表达式
    */
    #include<iostream>
    #include<cstdlib>
    #include<cctype>
    
    using namespace std;
    
    template<class T>
    class stack
    {
    private:
        T* base;
        T* top;
        int stackSize;
    public:
        stack(int a=100):stackSize(a)
        {
            base=top=new T[stackSize];
        }
        ~stack()
        {
            delete [] base;
            base=top=NULL;
            cout<<"stack析构
    ";
        }
        bool is_empty()const;
        bool is_full()const;
        bool pop(T &a);
        bool push(T a);
        int len()const;
    };
    
    template<class T>
    bool stack<T>::is_empty()const
    {
        if(base==top)
            return true;
        else
            return false;
    }
    
    template<class T>
    bool stack<T>::is_full()const
    {
        if(top-base==stackSize)
            return true;
        else
            return false;
    }
    
    template<class  T>
    bool stack<T>::push(T a)
    {
        if(!is_full())
        {
            *(top++)=a;
            return true;
        }
        else
            return false;;
        
    }
    
    template<class T>
    bool stack<T>::pop(T& a)
    {
        if(!is_empty())
        {
            a=*(--top);
            return true;
        }
        else
            return false;
    }
    
    template<class T>
    int stack<T>::len()const
    {
        cout<<(int*)base<<endl;
        cout<<(int*)top<<endl;
        return top-base;
    }
    
    double  postfix(char* str) // 计算后缀表达式
    {
        char c;
        stack<double>s;
        char bluff[10];
        
        int j=0;
        c=str[j++];
        while(c!='#')
        {
            int i=0;
            while(isdigit(c) || c=='.')//处理的数是double型的
            {
                bluff[i++]=c;// 用一块缓存区存储char型数据后转换
                
                if(i>=10)
                {
                    printf("
    输入的数过大
    ");
                    return 1;
                }
                c=str[j++];
                if(' '==c) // 处理数字后的空格,符号后的空格不管
                {
                    bluff[i]='';
                    i=0;
                    s.push(atof(bluff));
                    break;
                }
            }
            if('+'==c || '-'==c || '*'==c || '/'==c)
            {
                double d,e;
                s.pop(d);
                s.pop(e);
                switch(c)
                {
                case '+':
                    s.push(d+e);
                    break;
                case '-':
                    s.push(e-d);// 后出的减去前出的
                    break;
                case '*':
                    s.push(e*d);
                    break;
                case '/':
                    if(d !=0)
                        s.push(e/d);
                    else
                    {
                        printf("
    除数不能为0
    ");
                        return 1;
                    }
                    break;
                default:
                    printf("
    符号不能识别
    ");
                    return 1;
                }
            }
    
            c=str[j++];
        }
        double ans;
        s.pop(ans);
        
        return ans;    
    }
    
    char* mid2post(char* str, char*& str2)// 人机友好的中缀转换为合适计算机处理的后缀表达式
    {
        int i=0,j=0;
        stack<char>s;
        char e;
    
        char c=str[j++];
        while(c!='#')
        {
            while(isdigit(c) || '.'==c)
            {
                str2[i++]=c;
                c=str[j++]; //看下一个数是否还是数字
                if(' '==c || '#'==c) //空格结束,这里容易出错
                {
                    str2[i++]=' ';
                    break;
                }
            }
            if(')'==c) //遇到右括号,栈里肯定有符号
            {
                s.pop(e);
                while('('!=e)
                {
                    str2[i++]=e;
                    str2[i++]=' ';
                    s.pop(e);
                }
            }
            else if('+'==c || '-'==c)//
            {
                if(s.is_empty())//栈空,压栈
                {
                    s.push(c);
                }
                else //里面的优先级都高于这个+-
                {
                    do
                    {
                        s.pop(e);//弹出前面的符号,直到栈空或者遇到左括号
                        if('('==e)
                        {
                            s.push(e);
                        }
                        else
                        {
                            str2[i++]=e;
                            str2[i++]=' ';
                        }
                    }while('('!=e && !s.is_empty());
                    s.push(c);// 取出来后别忘了把这个符号再压栈
                }
            }
            else if('*'==c || '/'==c || '('==c)//保证栈里的符号优先级总是较低的
            {
                s.push(c);
            }
            if('#'==c)
                break;
            c=str[j++];
        }
    
        while(!s.is_empty())
        {
            s.pop(e);
            str2[i++]=e;
            str2[i++]=' ';
        }
        str2[--i]='#';//'#'之前不要空格,和逆波兰表达式匹配
        str2[++i]='';
        cout<<"后缀表达式:"<<str2<<endl;
        return str2;
    }
    
    double midfix(char *str)// 计算中缀表达式
    {
        //cout<<str<<endl;
        char* str2=new char[100]; 
        mid2post(str,str2);
    
        double ans=postfix(str2);
    
        delete str2;
    
        return ans;
    }
    
    
    
    int main()
    {
        char str[100];
        //printf("输入逆波兰表达式,元素之间用空格分开,并以#结束
    ");
        //cin.getline(str,100);
        //cout<<str<<endl;
        //printf("
    计算结果是%f
    ",postfix(str));
    
        printf("输入中缀表达式,元素之间用空格分开,并以#结束
    ");
        cin.getline(str,100);
        cout<<midfix(str)<<endl;
    
        return 0;
    }
  • 相关阅读:
    sqlserver2005存储汉字成问号解决办法:
    .net c# 日期格式和常用处理
    文件夹无法访问拒绝访问,无法删除文件的,快速有效解决方法
    打印出所有的 info.plist 中的 keys、values
    利用时间戳来准确计算某个时间点具现在的时间差
    项目中的技巧经验汇总
    "Base SDK Missing"问题的解决
    UIPopoverController的使用
    给ios自带控件添加圆角边的方法
    实现程序内截屏功能的代码
  • 原文地址:https://www.cnblogs.com/fkissx/p/4767081.html
Copyright © 2020-2023  润新知