• <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)鍵點在于中綴表達(dá)式轉(zhuǎn)后綴表達(dá)式,算法書上都有明確介紹就不多說了。動手實現(xiàn)了一個表達(dá)式解析器,支持括號、多位整數(shù)以及表達(dá)式合法性判斷。今天的狀態(tài)實在很差,本想對表達(dá)式進行合法性判斷的時候使用一些類似哈希表的技巧,比如使用一個大的bool數(shù)組,合法字符ASC碼對應(yīng)的項設(shè)置為1,比如可以直接判斷CHARS['+']是否為true,省去查找的時間。后來發(fā)現(xiàn)一共就支持那幾個字符,這樣做未免有點太矯情了。頭腦亂亂的,為了支持多位整數(shù),用了string,感覺怪怪的。

             /* -------------------------------------------------------------------------
            //    文件名        :    ExpParser.h
            //    創(chuàng)建者        :    dj
            //    創(chuàng)建時間    :    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á)式并計算
                {
                    
            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ōu)先級
                {
                    
            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)//判斷是否運算符
                {
                    
            switch(*s) {
                    
            case '+':
                    
            case '-':
                    
            case '*':
                    
            case '/':
                        
            return true;
                    
            default:
                        
            return false;
                    }

                }

                
            int Calc(const string& s1, const string& s2, const string& optr)//根據(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)        //計算后綴表達(dá)式的結(jié)果
                {
                    
            int n = 0;
                    strings::const_iterator it 
            = postExp.begin();
                    stack
            <string> st;                        //運算數(shù)臨時棧
                    for(; it != postExp.end(); it++)
                    
            {
                        
            if(IsNum(*it))                        //數(shù)字,直接入棧
                            st.push(*it);
                        
            else                                //運算符,取棧頂兩元素運算,結(jié)果進棧
                        {
                            
            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;                //臨時運算符棧
                    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 == "(")        //左括號,入運算符棧
                        {
                            st.push(
            *it);
                        }

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

                            st.pop();
                        }

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

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


                            st.push(
            *it);
                        }

                    }

                    
            while (!st.empty())                //棧內(nèi)剩余運算符出棧加入后綴表達(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;
            }

            神奇地數(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個數(shù)字,
            依順序輪值一次,
            到了第7天,
            它們就放假,
            由999999去代班。
            新年第一個周末快樂。
            posted on 2008-01-04 19:59 小四 閱讀(701) 評論(0)  編輯 收藏 引用 所屬分類: 算法與數(shù)據(jù)結(jié)構(gòu)
            欧美伊人久久大香线蕉综合| 欧美激情精品久久久久久久 | 亚洲国产日韩欧美综合久久| 久久夜色精品国产| 久久久久久综合网天天| 国产精品久久久久天天影视| 人人狠狠综合久久亚洲| 久久国产色AV免费看| 久久99精品久久久久久不卡| 精品综合久久久久久98| 亚洲午夜久久影院| 久久亚洲中文字幕精品一区| 久久精品国产免费一区| 亚洲精品tv久久久久久久久久| 69SEX久久精品国产麻豆| 亚洲精品久久久www| 久久久久波多野结衣高潮| 久久综合九色综合久99| 99久久香蕉国产线看观香| 一本久久a久久精品综合夜夜| 久久久久亚洲av成人无码电影| 久久人人爽人人爽人人片av麻烦 | 久久久WWW成人| 91久久婷婷国产综合精品青草| 亚洲精品tv久久久久久久久久| 99久久精品国产一区二区三区 | 午夜人妻久久久久久久久| 久久精品国产亚洲Aⅴ蜜臀色欲| 久久99亚洲网美利坚合众国| 久久婷婷午色综合夜啪| 久久久WWW成人免费毛片| 国产精品美女久久久网AV| 精品久久久噜噜噜久久久| 亚洲AV无码一区东京热久久| 大香伊人久久精品一区二区| 亚洲va久久久久| yy6080久久| 亚洲国产美女精品久久久久∴| 久久久黄色大片| 2020久久精品亚洲热综合一本| 亚洲性久久久影院|