• <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)
            一本色综合久久| 亚洲国产成人久久精品影视| 久久久久99精品成人片试看| 97久久国产综合精品女不卡| 久久久久99精品成人片直播| 久久99热精品| 免费无码国产欧美久久18| 嫩草伊人久久精品少妇AV| 欧美午夜精品久久久久久浪潮| 亚洲∧v久久久无码精品| 久久精品国产色蜜蜜麻豆| 亚洲午夜久久久久久久久电影网| 精品久久久无码21p发布| 欧美无乱码久久久免费午夜一区二区三区中文字幕 | 国产午夜免费高清久久影院| 久久精品亚洲男人的天堂| 久久久久亚洲国产| 久久美女人爽女人爽| 东方aⅴ免费观看久久av| 久久久青草久久久青草| 欧美午夜精品久久久久免费视| 国产精品无码久久久久| 久久综合亚洲欧美成人| 国产精品成人99久久久久| 久久精品午夜一区二区福利 | 99精品久久精品一区二区| 久久婷婷五月综合成人D啪| 93精91精品国产综合久久香蕉| 久久午夜夜伦鲁鲁片免费无码影视| 久久精品9988| 久久婷婷综合中文字幕| 久久精品一本到99热免费| 无码专区久久综合久中文字幕| 中文成人无码精品久久久不卡 | 久久久久人妻一区精品色| 国产成人无码精品久久久性色| 日韩欧美亚洲国产精品字幕久久久| 国内精品伊人久久久久影院对白 | 伊人久久大香线蕉亚洲五月天| 久久综合九色综合久99| 久久午夜福利无码1000合集|