zoukankan      html  css  js  c++  java
  • C++ 利用栈解决运算问题

    2017-06-27 19:19:18

    第一步需要将中缀表达式转为后缀表达式。这步的转化可以说是本题的核心。

    主要的转化手段是利用栈,有如下几个规则:

    • 数字直接输出
    • "("直接进栈
    • ")"将栈中元素出栈直到遇到"("
    • 其他运算符需要和栈顶元素比较优先级,如果栈顶元素的优先级小于等于待操作的运算符的,则需要出栈并输出。直到栈顶元素的优先级大于待处理元素
    • 最后需要将栈中元素清空,全部输出
    int toint(string in)
    {
        int rst;
        stringstream ss;
        ss<<in;
        ss>>rst;
        return rst;
    }
    
    int priority(char a)
    {
        switch(a)
        {
        case '*': return 2;
        case '/': return 2;
        case '+': return 1;
        case '-': return 1;
        case '(': return 3;
        case ')': return 3;
        }
    }
    
    bool isdig(char a)
    {
        if(a>='0'&&a<='9') return true;
        else return false;
    }
    
    //保证每次入栈的符号的优先级都比当前的栈顶元素要高,若此时栈顶的优先级比入栈元素低或者等于的话,则需要出栈
    //知道遇到比当前需要入栈元素优先级高的为止
    void midtopost(string in,vector<string>& vec)
    {
         stack<char> s;
         string rst="";
         int i=0;
         while(true)
         {     
             if(i>=in.length()) break;
             if(isdig(in[i]))
             {
                 string num="";
                 while(isdig(in[i])) num+=in[i++];
                 vec.push_back(num);
             }
             else
             {
                 if(s.empty()) s.push(in[i++]);
                 else
                 {
                     if(in[i]=='(') {s.push(in[i]);}
                     else if(in[i]==')')
                     {
                         while(s.top()!='(') 
                         {
                             string temp="";
                             temp+=s.top();
                             vec.push_back(temp);
                             s.pop();
                         }
                         s.pop();
                     }
                     else
                     {
                         if(priority(in[i])>priority(s.top())||s.top()=='(') s.push(in[i]);
                         else
                         {
                             //判断是否为空必须写在前面,符合短路原则
                             while(!s.empty()&&(priority(in[i])<=priority(s.top())))
                             {
                                 string temp="";
                                 temp+=s.top();
                                 vec.push_back(temp);
                                 s.pop();
                             }
                             s.push(in[i]);
                         }
                     }
                     ++i;
                 }
    
             }
         }
         //清空栈
         while(!s.empty())
         {
             string temp="";
             temp+=s.top();
             vec.push_back(temp);
             s.pop();
         }
    }
    
    //后缀表达式的计算,数字进栈,符号将栈顶两个元素出栈,运算后进栈
    int calc(vector<string>& vec)
    {
        stack<int> s;
        for(int i=0;i<vec.size();++i)
        {
            if(!vec[i].compare("*"))
            {
                int x=s.top();
                s.pop();
                int y=s.top();
                s.pop();
                s.push(x*y);
            }
            else if(!vec[i].compare("-"))
            {
                int x=s.top();
                s.pop();
                int y=s.top();
                s.pop();
                s.push(y-x);
            }
            else if(!vec[i].compare("+"))
            {
                int x=s.top();
                s.pop();
                int y=s.top();
                s.pop();
                s.push(x+y);
            }
            else if(!vec[i].compare("/"))
            {
                int x=s.top();
                s.pop();
                int y=s.top();
                s.pop();
                s.push(y/x);
            }
            else
            {
                s.push(toint(vec[i]));
            }
        }
        return s.top();
    }
    
    int main()
    { 
        string in="9+(3-1)*3+10/2";
        //string s="9 3 1 - 3 * + 10 2 / +";
        vector<string> vec;
        midtopost(in,vec);
        cout<<calc(vec)<<endl;
        return 0; 
    }
  • 相关阅读:
    常见RGB透明度对照表在这
    Android节假日图标动态替换方案
    用两个栈实现队列
    从头到尾打印链表 (链表/栈)
    MySQL常用函数
    找出数组中重复的数字
    两数之和
    java的list的几种排序写法整理(sort的用法)
    Java知识目录
    通过关键词来推荐话题
  • 原文地址:https://www.cnblogs.com/hyserendipity/p/7086302.html
Copyright © 2011-2022 走看看