• <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>
            隨筆 - 60, 文章 - 0, 評論 - 197, 引用 - 0
            數(shù)據(jù)加載中……

            用 C++ 實現(xiàn)的加、減、乘、除表達式計算

            前些日子面試一個開發(fā)工作,考官出了這么一筆試題目,要我寫出實現(xiàn)過程, 思量半天,終于
            用 C++ 完成,現(xiàn)將代碼貼出,與諸同道共分享。

            // 頭文件 Calc.h
            #ifndef __CALC_H__
            #define __CALC_H__

            #include <stack>

            #define ascii_int(x) (x >= 0x30 && x <= 0x39) ? (x - 0x30) : (x)
            const int GREATER =  1;
            const int EQUAL   =  0;
            const int LESS    = -1;

            class Calculate {
            public:
              int  evaluteExpr(char *exp);

            private:
              int  getLevel(char ch);
              bool isOperator(char ch);
              int  compareOpteratorLevel(char inputChar, char optrStackTop);
              int  calc(int num1, int num2, char op);
              void evaluate(char ch);

            private:
              std::stack<int>  _opnd_stack;
              std::stack<char> _optr_stack;
              static char _optr[];
              static int  _level[];
            };

            #endif


            // 頭文件的實現(xiàn)代碼 Calc.cxx
            #include "Calc.h"

            char Calculate::_optr[] = {'#', '(', '+', '-', '*', '/', ')'};
            int Calculate::_level[] = { 0,   1,   2,   2,   3,   3,   4 };

            // Get current operator level for calculating
            int Calculate::getLevel(char ch) {
              for (int i = 0; *(_optr+i) != '\0'; ++i)
                if (*(_optr+i) == ch)
                  return *(_level+i);
            }

            // Calculate the operands
            int Calculate::calc(int num1, int num2, char op) {
              switch (op)
                {
                case '+':
                  return num1 + num2;
                case '-':
                  return num1 - num2;
                case '*':
                  return num1 * num2;
                case '/':
                  return num1 / num2;
                }
            }

            // judge inputing character is operator or not
            bool Calculate::isOperator(char ch) {
              for (char *p = _optr; *p != '\0'; ++p)
                if (*p == ch)
                  return true;

              return false;
            }

            // Compare level of input operator and the top operator of operator stack
            int Calculate::compareOpteratorLevel(char inputChar, char optrStackTop) {
            //   if (inputChar == '(' && optrStackTop == ')')
            //     return EQUAL;
            //   else
              if (inputChar == '(')
                return GREATER;

              if (inputChar == ')' && optrStackTop == '(')
                return EQUAL;
              else if (inputChar == ')')
                return LESS;

              if (inputChar == '#' && optrStackTop == '#')
                return EQUAL;
            //   else if (inputChar == '#')
            //     return LESS;

              return (getLevel(inputChar) > getLevel(optrStackTop)) ? GREATER : LESS;
            }

            // Evaluate value while inputing operators
            void Calculate::evaluate(char ch) {
              char op;
              int num, result;

              if (!isOperator(ch)) {
                _opnd_stack.push(ascii_int(ch));
                return ;
              }

              switch (compareOpteratorLevel(ch, _optr_stack.top()))
                {
                case GREATER :
                  _optr_stack.push(ch);
                  break;

                case EQUAL :
                  _optr_stack.pop();
                  break;

                case LESS :
                  num = _opnd_stack.top();
                  _opnd_stack.pop();

                  result = _opnd_stack.top();
                  _opnd_stack.pop();

                  op = _optr_stack.top();
                  _optr_stack.pop();

                  result = calc(result, num, op);
                  _opnd_stack.push(result);
                  evaluate(ch);
                  break;
                }
            }

            // Evaluate user specified expression
            int Calculate::evaluteExpr(char *exp) {
              _optr_stack.push('#');
              for (char *p =exp; *p != '\0'; ++p )
                evaluate(*p);

              int result = _opnd_stack.top();
              _opnd_stack.pop();

              return result;
            }


            // 測試代碼 calc_test.cxx
            #include <iostream>
            #include "Calc.h"
            using namespace std;

            int main(void) {
              Calculate *calc = new Calculate();
              cout << "1+3*(4+7) = "
                   << calc->evaluteExpr("1+3*(4+7)#")
                   << endl;
              cout << "((1+2)) = "
                   << calc->evaluteExpr("((1+2))#")
                   << endl;
              cout << "3*8+9/7-5-9+(1-9)/4 = "
                   << calc->evaluteExpr("3*8+9/7-5-9+(1-9)/4#")
                   << endl;
              cout << "(6-7)*(5+9) = "
                   << calc->evaluteExpr("(6-7)*(5+9)#")
                   << endl;
              cout << "0*8+0/6-9+(7-1) = "
                   << calc->evaluteExpr("0*8+0/6-9+(7-1)#")
                   << endl;

              delete calc;
            }

            用 MinGW/G++ 3.4.5 編譯如下:
              g++  -o test.exe  Calc.cxx  Calc_test.cxx

            作為一個演示算法夠了, 但代碼還是有一些缺點:
               (1) 只能處理一位數(shù)的加、減、乘、除表達式計算(可帶括號)
               (2) 沒有任何錯誤處理,例如不能在表達式中有空格


            posted on 2008-01-02 10:01 Normandy 閱讀(5881) 評論(7)  編輯 收藏 引用 所屬分類: Programming

            評論

            # re: 用 C++ 實現(xiàn)的加、減、乘、除表達式計算[未登錄]  回復  更多評論   

            或者編譯里面的遞歸下降方法來分析表達式
            2008-01-02 12:27 | ngaut

            # re: 用 C++ 實現(xiàn)的加、減、乘、除表達式計算  回復  更多評論   

            利用動態(tài)數(shù)組,對掃描結(jié)果進行臨時存儲,那樣的話可以實現(xiàn)和計算器一樣的復雜表達式的計算

            # re: 用 C++ 實現(xiàn)的加、減、乘、除表達式計算  回復  更多評論   

            見數(shù)據(jù)結(jié)構(gòu)里。先轉(zhuǎn)換到后序表達式再算
            2008-01-03 15:57 | Zeus2

            # re: 用 C++ 實現(xiàn)的加、減、乘、除表達式計算  回復  更多評論   

            解決問題的思路不錯!學習
            2008-01-07 11:13 | kyle

            # re: 用 C++ 實現(xiàn)的加、減、乘、除表達式計算  回復  更多評論   

            可以使用算符優(yōu)先級,用棧記錄算符和操作數(shù)。也可以像編譯一樣先分詞再語法分析生成語法樹就可以直接算了
            2008-02-02 10:40 | 張磊

            # re: 用 C++ 實現(xiàn)的加、減、乘、除表達式計算  回復  更多評論   

            用什么堆棧啊,高手的話直接用遞歸
            2009-08-31 16:04 | jj

            # re: 用 C++ 實現(xiàn)的加、減、乘、除表達式計算  回復  更多評論   

            @jj
            不直到就不要亂說,能不用遞歸的都不要用!
            2009-09-18 11:19 | zigzag
            蜜桃麻豆WWW久久囤产精品| 香蕉久久夜色精品国产小说| 国产高清美女一级a毛片久久w| www.久久精品| 久久亚洲国产精品五月天婷| 久久国产劲爆AV内射—百度| 久久精品人成免费| 久久成人精品| 久久精品国产2020| 久久国产热这里只有精品| 亚洲欧美国产精品专区久久| 久久久久女人精品毛片| 国产亚洲美女精品久久久| 久久热这里只有精品在线观看| 国内精品久久久久影院优| 久久久久无码国产精品不卡| 色偷偷偷久久伊人大杳蕉| 久久久久18| 久久精品一区二区| 国内精品久久久久影院薰衣草| 久久香蕉综合色一综合色88| 色综合久久久久综合体桃花网| 久久久久人妻精品一区三寸蜜桃| 69国产成人综合久久精品| 久久99国产精品久久99小说 | 成人久久精品一区二区三区| 一本色道久久88综合日韩精品 | 久久这里只精品99re66| 国内精品欧美久久精品| 国产精品久久久久jk制服| 青青草原综合久久大伊人| 久久婷婷五月综合色99啪ak| 精品久久久久久无码中文字幕 | 日韩久久久久久中文人妻 | 一本久久a久久精品综合香蕉| 品成人欧美大片久久国产欧美... 品成人欧美大片久久国产欧美 | 国产精品一区二区久久精品无码| 久久精品国产一区| 国产精品99久久不卡| 久久国产成人| 亚洲国产成人久久精品99|