• <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)
            国产精品美女久久久| 人妻精品久久久久中文字幕69| 久久婷婷五月综合国产尤物app| 久久精品国产一区二区电影| 日本一区精品久久久久影院| 欧美亚洲另类久久综合| 久久99久久无码毛片一区二区 | 久久99国产一区二区三区| 久久久WWW成人免费精品| 久久亚洲高清综合| 久久精品无码午夜福利理论片| 久久香蕉一级毛片| 国产精品久久久久蜜芽| 色偷偷88888欧美精品久久久| 久久婷婷久久一区二区三区| 久久人人爽人人人人片av| 国产午夜精品久久久久免费视 | 久久午夜免费视频| 99久久超碰中文字幕伊人 | 久久精品国产欧美日韩99热| 2021国产精品午夜久久| 国产亚州精品女人久久久久久| 午夜精品久久久久久久| 精品水蜜桃久久久久久久| 无码AV中文字幕久久专区| 久久久久九国产精品| 久久久久中文字幕| 亚洲成色www久久网站夜月| 国产成人综合久久精品红| 伊人色综合久久天天| 精品精品国产自在久久高清| 99久久做夜夜爱天天做精品| 久久久久久国产a免费观看不卡| 色综合久久精品中文字幕首页 | 国产精品久久久久…| 久久久午夜精品福利内容| 一本大道久久a久久精品综合| 国产精品久久久久久一区二区三区| 欧美亚洲国产精品久久高清| 久久久久人妻精品一区三寸蜜桃| 国产AV影片久久久久久|