• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            小四的海市蜃樓
            Never surrender to complexity
            posts - 21,comments - 59,trackbacks - 0
            表達(dá)式求值的關(guān)鍵點(diǎn)在于中綴表達(dá)式轉(zhuǎn)后綴表達(dá)式,算法書上都有明確介紹就不多說(shuō)了。動(dòng)手實(shí)現(xiàn)了一個(gè)表達(dá)式解析器,支持括號(hào)、多位整數(shù)以及表達(dá)式合法性判斷。今天的狀態(tài)實(shí)在很差,本想對(duì)表達(dá)式進(jìn)行合法性判斷的時(shí)候使用一些類似哈希表的技巧,比如使用一個(gè)大的bool數(shù)組,合法字符ASC碼對(duì)應(yīng)的項(xiàng)設(shè)置為1,比如可以直接判斷CHARS['+']是否為true,省去查找的時(shí)間。后來(lái)發(fā)現(xiàn)一共就支持那幾個(gè)字符,這樣做未免有點(diǎn)太矯情了。頭腦亂亂的,為了支持多位整數(shù),用了string,感覺(jué)怪怪的。

             /* -------------------------------------------------------------------------
            //    文件名        :    ExpParser.h
            //    創(chuàng)建者        :    dj
            //    創(chuàng)建時(shí)間    :    2008-1-4 18:35
            //    功能描述    :    表達(dá)式求值
            // -----------------------------------------------------------------------
            */


            #ifndef __EXPPARSER_H__
            #define __EXPPARSER_H__

            #include 
            <vector>
            #include 
            <string>
            using namespace std;
            typedef vector
            <string> strings;

            class ExpParser
            {
            public:
                
            int CalcExp(const char* sExp)    //解析表達(dá)式并計(jì)算
                {
                    
            if (!CheckExp(sExp))
                    
            {
                        
            return 0;
                    }

                    strings inExp;
                    strings postExp;
                    GetInExp(inExp, sExp);
                    GetPostExp(postExp, inExp);    
                    
            return CalcPostExp(postExp);
                }

            private:
                inline 
            int OptrPRI(const string& s)    //得到運(yùn)算符優(yōu)先級(jí)
                {
                    
            switch(s[0]) 
                    
            {
                    
            case '*':
                    
            case '/':
                        
            return 3;
                    
            case '+':
                    
            case '-':
                        
            return 2;
                    
            case '(':
                        
            return 1;
                    
            case '#':
                        
            return 0;
                    
            default:
                        
            return -1;
                    }

                }
                
                inline 
            bool IsNum(const char* s)        //判斷是否數(shù)字
                {
                    
            return (*s<='9'&&*s>='0');
                }

                inline 
            bool IsNum(const string& s)
                
            {
                    
            return (IsNum(&s[0]));
                }

                inline 
            bool IsOptr(const char* s)//判斷是否運(yùn)算符
                {
                    
            switch(*s) {
                    
            case '+':
                    
            case '-':
                    
            case '*':
                    
            case '/':
                        
            return true;
                    
            default:
                        
            return false;
                    }

                }

                
            int Calc(const string& s1, const string& s2, const string& optr)//根據(jù)運(yùn)算符計(jì)算結(jié)果
                {
                    
            int n1 = atoi(s1.c_str());
                    
            int n2 = atoi(s2.c_str());
                    
            if (optr == "+")
                    
            {
                        
            return n1+n2;
                    }

                    
            else if (optr == "-")
                    
            {
                        
            return n1-n2;
                    }

                    
            else if (optr == "*")
                    
            {
                        
            return n1*n2;
                    }

                    
            else if (optr == "/")
                    
            {
                        
            return n1/n2;
                    }

                    assert(
            false);
                    
            return 0;
                }

                
            int CalcPostExp(const strings& postExp)        //計(jì)算后綴表達(dá)式的結(jié)果
                {
                    
            int n = 0;
                    strings::const_iterator it 
            = postExp.begin();
                    stack
            <string> st;                        //運(yùn)算數(shù)臨時(shí)棧
                    for(; it != postExp.end(); it++)
                    
            {
                        
            if(IsNum(*it))                        //數(shù)字,直接入棧
                            st.push(*it);
                        
            else                                //運(yùn)算符,取棧頂兩元素運(yùn)算,結(jié)果進(jìn)棧
                        {
                            
            string s1 = st.top(); st.pop();
                            
            string s2 = st.top(); st.pop();
                            n 
            = Calc(s2, s1, *it);
                            
            char a[255];
                            itoa(n, a, 
            10);
                            st.push(a);
                        }

                    }

                    
            return n;
                }

                
            bool CheckExp(const char* sExp)                    //檢查表達(dá)式合法性
                {
                    stack
            <char> st;
                    
            const char* p = sExp;
                    
            bool bPrevOptr = true;
                    
            while(*p!=NULL)
                    
            {
                        
            if (IsOptr(p))
                        
            {
                            
            if (bPrevOptr)
                            
            {
                                cout
            <<"illegal expression"<<endl;
                                
            return false;
                            }

                            bPrevOptr 
            = true;
                        }

                        
            else
                        
            {
                            bPrevOptr 
            = false;
                            
            if (*p=='(')
                            
            {
                                st.push(
            *p);
                            }

                            
            else if (*p==')')
                            
            {
                                
            if(st.empty())
                                
            {
                                    cout
            <<"a '(' is expected"<<endl;
                                    
            return false;
                                }

                                st.pop();            
                            }

                            
            else if (!IsNum(p))
                            
            {
                                cout
            <<"unexpected symbol"<<endl;
                                
            return false;
                            }

                        }

                        p
            ++;
                    }
                
                    
            if (!st.empty())
                    
            {
                        cout
            <<"a ')' is expected"<<endl;
                        
            return false;
                    }

                    
            return true;
                }

                
                
            void GetInExp(strings& inExp, const char* sExp)//根據(jù)原始字符串得到中綴表達(dá)式
                {
                    
            string s;
                    
            int nLen = strlen(sExp);
                    
            for (int i = 0; i < nLen; i++)
                    
            {
                        
            if (IsNum(&sExp[i]))
                        
            {
                            s 
            += sExp[i];
                            
            if (!IsNum(&sExp[i+1])) 
                            
            {
                                inExp.push_back(s);
                            }

                        }
                        
                        
            else
                        
            {
                            s 
            = sExp[i];
                            inExp.push_back(s);
                            s.erase();
                        }

                    }

                }
                
                
            void GetPostExp(strings& postExp, const strings& inExp)//根據(jù)中綴表達(dá)式得到后綴表達(dá)式
                {
                    stack
            <string> st;                //臨時(shí)運(yùn)算符棧
                    st.push("#");
                    strings::const_iterator it 
            = inExp.begin();
                    
            for(; it != inExp.end(); it++)
                    
            {
                        
            if (IsNum(*it))                //數(shù)字直接加入后綴表達(dá)式
                        {
                            postExp.push_back(
            *it);
                        }

                        
            else if (*it == "(")        //左括號(hào),入運(yùn)算符棧
                        {
                            st.push(
            *it);
                        }

                        
            else if (*it == ")")        //右括號(hào),到左括號(hào)之間的運(yùn)算符出棧加入后綴表達(dá)式
                        {
                            
            while(st.top()!="(")
                            
            {
                                postExp.push_back(st.top());
                                st.pop();
                            }

                            st.pop();
                        }

                        
            else                        //其它運(yùn)算符,出棧直到大于棧頂元素優(yōu)先級(jí)
                        {
                            
            int nPRI = OptrPRI(*it);

                            
            while (nPRI<=OptrPRI(st.top()))
                            
            {
                                postExp.push_back(st.top());
                                st.pop();
                            }


                            st.push(
            *it);
                        }

                    }

                    
            while (!st.empty())                //棧內(nèi)剩余運(yùn)算符出棧加入后綴表達(dá)式
                    {
                        
            if (st.top()!="#")
                            postExp.push_back(st.top());
                        st.pop();
                    }

                }

            }
            ;

            #endif

             

            int main(int argc, char* argv[])
            {
                ExpParser ep;
                
            int n = ep.CalcExp("7*(857+142*1000)");
                cout
            <<n<<endl;
                
            return 0;
            }

            神奇地?cái)?shù),142857,
            142857*1=142857
            142857*2=285714
            142857*3=428571
            142857*4=571428
            142857*5=714285
            142857*6=857142
            142857*7=999999
            它發(fā)現(xiàn)于埃及金字塔內(nèi),
            它證明一星期有7天,
            它自我累加一次,
            就由它的6個(gè)數(shù)字,
            依順序輪值一次,
            到了第7天,
            它們就放假,
            由999999去代班。
            新年第一個(gè)周末快樂(lè)。
            posted on 2008-01-04 19:59 小四 閱讀(701) 評(píng)論(0)  編輯 收藏 引用 所屬分類: 算法與數(shù)據(jù)結(jié)構(gòu)
            久久这里只有精品首页| 色偷偷88欧美精品久久久| 色婷婷综合久久久久中文| 伊人久久综合成人网| 国产精品久久久久久久久免费| 久久久青草久久久青草| 久久99精品九九九久久婷婷| 久久精品国产精品亚洲精品 | 久久精品国产亚洲AV久| 久久精品国产清高在天天线| 久久伊人五月天论坛| 国产精品9999久久久久| 亚洲国产成人久久综合一区77| 久久精品国产亚洲AV香蕉| 久久久久久国产a免费观看不卡| 久久青青草原亚洲av无码app| 久久毛片免费看一区二区三区| 国产精品久久毛片完整版| 欧美亚洲国产精品久久高清| 国产L精品国产亚洲区久久| 亚洲精品午夜国产VA久久成人| 精品无码久久久久久久久久 | 国产精品久久久久影视不卡| 日本WV一本一道久久香蕉| 久久一本综合| 久久久久亚洲AV成人网| 色综合久久88色综合天天| 亚洲精品高清国产一线久久| 亚洲日韩欧美一区久久久久我| 国产精品一区二区久久精品无码| 狠狠色婷婷久久一区二区三区 | 中文成人久久久久影院免费观看| 亚洲乱亚洲乱淫久久| 久久精品成人国产午夜| 狠狠88综合久久久久综合网| 色综合久久久久久久久五月| 久久这里只有精品首页| 亚洲伊人久久精品影院| 99精品久久精品一区二区| 亚洲AV日韩AV永久无码久久| 久久久久久久久波多野高潮|